{
 "cells": [
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-06T01:04:16.200060Z",
     "start_time": "2025-03-06T01:04:08.705547Z"
    }
   },
   "source": [
    "import matplotlib as mpl\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n",
    "import numpy as np\n",
    "import sklearn\n",
    "import pandas as pd\n",
    "import os\n",
    "import sys\n",
    "import time\n",
    "from tqdm.auto import tqdm\n",
    "import torch\n",
    "import torch.nn as nn\n",
    "import torch.nn.functional as F\n",
    "\n",
    "print(sys.version_info)\n",
    "for module in mpl, np, pd, sklearn, torch:\n",
    "    print(module.__name__, module.__version__)\n",
    "    \n",
    "device = torch.device(\"cuda:0\") if torch.cuda.is_available() else torch.device(\"cpu\")\n",
    "print(device)\n"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "sys.version_info(major=3, minor=12, micro=3, releaselevel='final', serial=0)\n",
      "matplotlib 3.9.1\n",
      "numpy 2.0.0\n",
      "pandas 2.2.2\n",
      "sklearn 1.6.1\n",
      "torch 2.6.0+cu126\n",
      "cuda:0\n"
     ]
    }
   ],
   "execution_count": 1
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 准备数据"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-06T01:04:16.460918Z",
     "start_time": "2025-03-06T01:04:16.200060Z"
    }
   },
   "source": [
    "from sklearn.datasets import fetch_california_housing\n",
    "\n",
    "housing = fetch_california_housing(data_home='data')\n",
    "print(housing.DESCR)\n",
    "print(housing.data.shape)\n",
    "print(housing.target.shape)"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      ".. _california_housing_dataset:\n",
      "\n",
      "California Housing dataset\n",
      "--------------------------\n",
      "\n",
      "**Data Set Characteristics:**\n",
      "\n",
      ":Number of Instances: 20640\n",
      "\n",
      ":Number of Attributes: 8 numeric, predictive attributes and the target\n",
      "\n",
      ":Attribute Information:\n",
      "    - MedInc        median income in block group\n",
      "    - HouseAge      median house age in block group\n",
      "    - AveRooms      average number of rooms per household\n",
      "    - AveBedrms     average number of bedrooms per household\n",
      "    - Population    block group population\n",
      "    - AveOccup      average number of household members\n",
      "    - Latitude      block group latitude\n",
      "    - Longitude     block group longitude\n",
      "\n",
      ":Missing Attribute Values: None\n",
      "\n",
      "This dataset was obtained from the StatLib repository.\n",
      "https://www.dcc.fc.up.pt/~ltorgo/Regression/cal_housing.html\n",
      "\n",
      "The target variable is the median house value for California districts,\n",
      "expressed in hundreds of thousands of dollars ($100,000).\n",
      "\n",
      "This dataset was derived from the 1990 U.S. census, using one row per census\n",
      "block group. A block group is the smallest geographical unit for which the U.S.\n",
      "Census Bureau publishes sample data (a block group typically has a population\n",
      "of 600 to 3,000 people).\n",
      "\n",
      "A household is a group of people residing within a home. Since the average\n",
      "number of rooms and bedrooms in this dataset are provided per household, these\n",
      "columns may take surprisingly large values for block groups with few households\n",
      "and many empty houses, such as vacation resorts.\n",
      "\n",
      "It can be downloaded/loaded using the\n",
      ":func:`sklearn.datasets.fetch_california_housing` function.\n",
      "\n",
      ".. rubric:: References\n",
      "\n",
      "- Pace, R. Kelley and Ronald Barry, Sparse Spatial Autoregressions,\n",
      "  Statistics and Probability Letters, 33 (1997) 291-297\n",
      "\n",
      "(20640, 8)\n",
      "(20640,)\n"
     ]
    }
   ],
   "execution_count": 2
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-06T01:04:16.464408Z",
     "start_time": "2025-03-06T01:04:16.460918Z"
    }
   },
   "source": [
    "# print(housing.data[0:5])\n",
    "import pprint  #打印的格式比较 好看\n",
    "\n",
    "pprint.pprint(housing.data[0:2])\n",
    "print('-'*50)\n",
    "pprint.pprint(housing.target[0:2])"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "array([[ 8.32520000e+00,  4.10000000e+01,  6.98412698e+00,\n",
      "         1.02380952e+00,  3.22000000e+02,  2.55555556e+00,\n",
      "         3.78800000e+01, -1.22230000e+02],\n",
      "       [ 8.30140000e+00,  2.10000000e+01,  6.23813708e+00,\n",
      "         9.71880492e-01,  2.40100000e+03,  2.10984183e+00,\n",
      "         3.78600000e+01, -1.22220000e+02]])\n",
      "--------------------------------------------------\n",
      "array([4.526, 3.585])\n"
     ]
    }
   ],
   "execution_count": 3
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-06T01:04:16.740105Z",
     "start_time": "2025-03-06T01:04:16.464408Z"
    }
   },
   "source": [
    "from sklearn.model_selection import train_test_split\n",
    "\n",
    "#拆分训练集和测试集，random_state是随机种子,同样的随机数种子，是为了得到同样的随机值\n",
    "x_train_all, x_test, y_train_all, y_test = train_test_split(\n",
    "    housing.data, housing.target, random_state = 7)\n",
    "x_train, x_valid, y_train, y_valid = train_test_split(\n",
    "    x_train_all, y_train_all, random_state = 11)\n",
    "# 训练集\n",
    "print(x_train.shape, y_train.shape)\n",
    "# 验证集\n",
    "print(x_valid.shape, y_valid.shape)\n",
    "# 测试集\n",
    "print(x_test.shape, y_test.shape)\n",
    "\n",
    "dataset_maps = {\n",
    "    \"train\": [x_train, y_train], #训练集\n",
    "    \"valid\": [x_valid, y_valid], #验证集\n",
    "    \"test\": [x_test, y_test], #测试集\n",
    "} #把3个数据集都放到字典中\n"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(11610, 8) (11610,)\n",
      "(3870, 8) (3870,)\n",
      "(5160, 8) (5160,)\n"
     ]
    }
   ],
   "execution_count": 4
  },
  {
   "cell_type": "code",
   "source": [
    "type(x_train)"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-03-06T01:04:16.744941Z",
     "start_time": "2025-03-06T01:04:16.741109Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "numpy.ndarray"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 5
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-06T01:04:16.752985Z",
     "start_time": "2025-03-06T01:04:16.744941Z"
    }
   },
   "source": [
    "from sklearn.preprocessing import StandardScaler\n",
    "\n",
    "\n",
    "\n",
    "scaler = StandardScaler() #标准化\n",
    "scaler.fit(x_train) #fit和fit_transform的区别，fit是计算均值和方差，fit_transform是先fit，然后transform"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "StandardScaler()"
      ],
      "text/html": [
       "<style>#sk-container-id-1 {\n",
       "  /* Definition of color scheme common for light and dark mode */\n",
       "  --sklearn-color-text: #000;\n",
       "  --sklearn-color-text-muted: #666;\n",
       "  --sklearn-color-line: gray;\n",
       "  /* Definition of color scheme for unfitted estimators */\n",
       "  --sklearn-color-unfitted-level-0: #fff5e6;\n",
       "  --sklearn-color-unfitted-level-1: #f6e4d2;\n",
       "  --sklearn-color-unfitted-level-2: #ffe0b3;\n",
       "  --sklearn-color-unfitted-level-3: chocolate;\n",
       "  /* Definition of color scheme for fitted estimators */\n",
       "  --sklearn-color-fitted-level-0: #f0f8ff;\n",
       "  --sklearn-color-fitted-level-1: #d4ebff;\n",
       "  --sklearn-color-fitted-level-2: #b3dbfd;\n",
       "  --sklearn-color-fitted-level-3: cornflowerblue;\n",
       "\n",
       "  /* Specific color for light theme */\n",
       "  --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n",
       "  --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, white)));\n",
       "  --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n",
       "  --sklearn-color-icon: #696969;\n",
       "\n",
       "  @media (prefers-color-scheme: dark) {\n",
       "    /* Redefinition of color scheme for dark theme */\n",
       "    --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n",
       "    --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, #111)));\n",
       "    --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n",
       "    --sklearn-color-icon: #878787;\n",
       "  }\n",
       "}\n",
       "\n",
       "#sk-container-id-1 {\n",
       "  color: var(--sklearn-color-text);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 pre {\n",
       "  padding: 0;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 input.sk-hidden--visually {\n",
       "  border: 0;\n",
       "  clip: rect(1px 1px 1px 1px);\n",
       "  clip: rect(1px, 1px, 1px, 1px);\n",
       "  height: 1px;\n",
       "  margin: -1px;\n",
       "  overflow: hidden;\n",
       "  padding: 0;\n",
       "  position: absolute;\n",
       "  width: 1px;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-dashed-wrapped {\n",
       "  border: 1px dashed var(--sklearn-color-line);\n",
       "  margin: 0 0.4em 0.5em 0.4em;\n",
       "  box-sizing: border-box;\n",
       "  padding-bottom: 0.4em;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-container {\n",
       "  /* jupyter's `normalize.less` sets `[hidden] { display: none; }`\n",
       "     but bootstrap.min.css set `[hidden] { display: none !important; }`\n",
       "     so we also need the `!important` here to be able to override the\n",
       "     default hidden behavior on the sphinx rendered scikit-learn.org.\n",
       "     See: https://github.com/scikit-learn/scikit-learn/issues/21755 */\n",
       "  display: inline-block !important;\n",
       "  position: relative;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-text-repr-fallback {\n",
       "  display: none;\n",
       "}\n",
       "\n",
       "div.sk-parallel-item,\n",
       "div.sk-serial,\n",
       "div.sk-item {\n",
       "  /* draw centered vertical line to link estimators */\n",
       "  background-image: linear-gradient(var(--sklearn-color-text-on-default-background), var(--sklearn-color-text-on-default-background));\n",
       "  background-size: 2px 100%;\n",
       "  background-repeat: no-repeat;\n",
       "  background-position: center center;\n",
       "}\n",
       "\n",
       "/* Parallel-specific style estimator block */\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item::after {\n",
       "  content: \"\";\n",
       "  width: 100%;\n",
       "  border-bottom: 2px solid var(--sklearn-color-text-on-default-background);\n",
       "  flex-grow: 1;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel {\n",
       "  display: flex;\n",
       "  align-items: stretch;\n",
       "  justify-content: center;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  position: relative;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item {\n",
       "  display: flex;\n",
       "  flex-direction: column;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item:first-child::after {\n",
       "  align-self: flex-end;\n",
       "  width: 50%;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item:last-child::after {\n",
       "  align-self: flex-start;\n",
       "  width: 50%;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item:only-child::after {\n",
       "  width: 0;\n",
       "}\n",
       "\n",
       "/* Serial-specific style estimator block */\n",
       "\n",
       "#sk-container-id-1 div.sk-serial {\n",
       "  display: flex;\n",
       "  flex-direction: column;\n",
       "  align-items: center;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  padding-right: 1em;\n",
       "  padding-left: 1em;\n",
       "}\n",
       "\n",
       "\n",
       "/* Toggleable style: style used for estimator/Pipeline/ColumnTransformer box that is\n",
       "clickable and can be expanded/collapsed.\n",
       "- Pipeline and ColumnTransformer use this feature and define the default style\n",
       "- Estimators will overwrite some part of the style using the `sk-estimator` class\n",
       "*/\n",
       "\n",
       "/* Pipeline and ColumnTransformer style (default) */\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable {\n",
       "  /* Default theme specific background. It is overwritten whether we have a\n",
       "  specific estimator or a Pipeline/ColumnTransformer */\n",
       "  background-color: var(--sklearn-color-background);\n",
       "}\n",
       "\n",
       "/* Toggleable label */\n",
       "#sk-container-id-1 label.sk-toggleable__label {\n",
       "  cursor: pointer;\n",
       "  display: flex;\n",
       "  width: 100%;\n",
       "  margin-bottom: 0;\n",
       "  padding: 0.5em;\n",
       "  box-sizing: border-box;\n",
       "  text-align: center;\n",
       "  align-items: start;\n",
       "  justify-content: space-between;\n",
       "  gap: 0.5em;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 label.sk-toggleable__label .caption {\n",
       "  font-size: 0.6rem;\n",
       "  font-weight: lighter;\n",
       "  color: var(--sklearn-color-text-muted);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 label.sk-toggleable__label-arrow:before {\n",
       "  /* Arrow on the left of the label */\n",
       "  content: \"▸\";\n",
       "  float: left;\n",
       "  margin-right: 0.25em;\n",
       "  color: var(--sklearn-color-icon);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 label.sk-toggleable__label-arrow:hover:before {\n",
       "  color: var(--sklearn-color-text);\n",
       "}\n",
       "\n",
       "/* Toggleable content - dropdown */\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable__content {\n",
       "  max-height: 0;\n",
       "  max-width: 0;\n",
       "  overflow: hidden;\n",
       "  text-align: left;\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable__content.fitted {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable__content pre {\n",
       "  margin: 0.2em;\n",
       "  border-radius: 0.25em;\n",
       "  color: var(--sklearn-color-text);\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable__content.fitted pre {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 input.sk-toggleable__control:checked~div.sk-toggleable__content {\n",
       "  /* Expand drop-down */\n",
       "  max-height: 200px;\n",
       "  max-width: 100%;\n",
       "  overflow: auto;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 input.sk-toggleable__control:checked~label.sk-toggleable__label-arrow:before {\n",
       "  content: \"▾\";\n",
       "}\n",
       "\n",
       "/* Pipeline/ColumnTransformer-specific style */\n",
       "\n",
       "#sk-container-id-1 div.sk-label input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-label.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Estimator-specific style */\n",
       "\n",
       "/* Colorize estimator box */\n",
       "#sk-container-id-1 div.sk-estimator input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-estimator.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-label label.sk-toggleable__label,\n",
       "#sk-container-id-1 div.sk-label label {\n",
       "  /* The background is the default theme color */\n",
       "  color: var(--sklearn-color-text-on-default-background);\n",
       "}\n",
       "\n",
       "/* On hover, darken the color of the background */\n",
       "#sk-container-id-1 div.sk-label:hover label.sk-toggleable__label {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "/* Label box, darken color on hover, fitted */\n",
       "#sk-container-id-1 div.sk-label.fitted:hover label.sk-toggleable__label.fitted {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Estimator label */\n",
       "\n",
       "#sk-container-id-1 div.sk-label label {\n",
       "  font-family: monospace;\n",
       "  font-weight: bold;\n",
       "  display: inline-block;\n",
       "  line-height: 1.2em;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-label-container {\n",
       "  text-align: center;\n",
       "}\n",
       "\n",
       "/* Estimator-specific */\n",
       "#sk-container-id-1 div.sk-estimator {\n",
       "  font-family: monospace;\n",
       "  border: 1px dotted var(--sklearn-color-border-box);\n",
       "  border-radius: 0.25em;\n",
       "  box-sizing: border-box;\n",
       "  margin-bottom: 0.5em;\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-estimator.fitted {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "/* on hover */\n",
       "#sk-container-id-1 div.sk-estimator:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-estimator.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Specification for estimator info (e.g. \"i\" and \"?\") */\n",
       "\n",
       "/* Common style for \"i\" and \"?\" */\n",
       "\n",
       ".sk-estimator-doc-link,\n",
       "a:link.sk-estimator-doc-link,\n",
       "a:visited.sk-estimator-doc-link {\n",
       "  float: right;\n",
       "  font-size: smaller;\n",
       "  line-height: 1em;\n",
       "  font-family: monospace;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  border-radius: 1em;\n",
       "  height: 1em;\n",
       "  width: 1em;\n",
       "  text-decoration: none !important;\n",
       "  margin-left: 0.5em;\n",
       "  text-align: center;\n",
       "  /* unfitted */\n",
       "  border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-unfitted-level-1);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link.fitted,\n",
       "a:link.sk-estimator-doc-link.fitted,\n",
       "a:visited.sk-estimator-doc-link.fitted {\n",
       "  /* fitted */\n",
       "  border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-fitted-level-1);\n",
       "}\n",
       "\n",
       "/* On hover */\n",
       "div.sk-estimator:hover .sk-estimator-doc-link:hover,\n",
       ".sk-estimator-doc-link:hover,\n",
       "div.sk-label-container:hover .sk-estimator-doc-link:hover,\n",
       ".sk-estimator-doc-link:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "div.sk-estimator.fitted:hover .sk-estimator-doc-link.fitted:hover,\n",
       ".sk-estimator-doc-link.fitted:hover,\n",
       "div.sk-label-container:hover .sk-estimator-doc-link.fitted:hover,\n",
       ".sk-estimator-doc-link.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "/* Span, style for the box shown on hovering the info icon */\n",
       ".sk-estimator-doc-link span {\n",
       "  display: none;\n",
       "  z-index: 9999;\n",
       "  position: relative;\n",
       "  font-weight: normal;\n",
       "  right: .2ex;\n",
       "  padding: .5ex;\n",
       "  margin: .5ex;\n",
       "  width: min-content;\n",
       "  min-width: 20ex;\n",
       "  max-width: 50ex;\n",
       "  color: var(--sklearn-color-text);\n",
       "  box-shadow: 2pt 2pt 4pt #999;\n",
       "  /* unfitted */\n",
       "  background: var(--sklearn-color-unfitted-level-0);\n",
       "  border: .5pt solid var(--sklearn-color-unfitted-level-3);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link.fitted span {\n",
       "  /* fitted */\n",
       "  background: var(--sklearn-color-fitted-level-0);\n",
       "  border: var(--sklearn-color-fitted-level-3);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link:hover span {\n",
       "  display: block;\n",
       "}\n",
       "\n",
       "/* \"?\"-specific style due to the `<a>` HTML tag */\n",
       "\n",
       "#sk-container-id-1 a.estimator_doc_link {\n",
       "  float: right;\n",
       "  font-size: 1rem;\n",
       "  line-height: 1em;\n",
       "  font-family: monospace;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  border-radius: 1rem;\n",
       "  height: 1rem;\n",
       "  width: 1rem;\n",
       "  text-decoration: none;\n",
       "  /* unfitted */\n",
       "  color: var(--sklearn-color-unfitted-level-1);\n",
       "  border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 a.estimator_doc_link.fitted {\n",
       "  /* fitted */\n",
       "  border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-fitted-level-1);\n",
       "}\n",
       "\n",
       "/* On hover */\n",
       "#sk-container-id-1 a.estimator_doc_link:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 a.estimator_doc_link.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-3);\n",
       "}\n",
       "</style><div id=\"sk-container-id-1\" class=\"sk-top-container\"><div class=\"sk-text-repr-fallback\"><pre>StandardScaler()</pre><b>In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. <br />On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.</b></div><div class=\"sk-container\" hidden><div class=\"sk-item\"><div class=\"sk-estimator fitted sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-1\" type=\"checkbox\" checked><label for=\"sk-estimator-id-1\" class=\"sk-toggleable__label fitted sk-toggleable__label-arrow\"><div><div>StandardScaler</div></div><div><a class=\"sk-estimator-doc-link fitted\" rel=\"noreferrer\" target=\"_blank\" href=\"https://scikit-learn.org/1.6/modules/generated/sklearn.preprocessing.StandardScaler.html\">?<span>Documentation for StandardScaler</span></a><span class=\"sk-estimator-doc-link fitted\">i<span>Fitted</span></span></div></label><div class=\"sk-toggleable__content fitted\"><pre>StandardScaler()</pre></div> </div></div></div></div>"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 6
  },
  {
   "cell_type": "code",
   "source": [
    "np.array(1).shape"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-03-06T01:04:16.756804Z",
     "start_time": "2025-03-06T01:04:16.752985Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "()"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 7
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 构建数据集"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-06T01:04:16.766597Z",
     "start_time": "2025-03-06T01:04:16.756804Z"
    }
   },
   "source": [
    "#构建私有数据集，就需要用如下方式\n",
    "from torch.utils.data import Dataset\n",
    "\n",
    "class HousingDataset(Dataset):\n",
    "    def __init__(self, mode='train'):\n",
    "        self.x, self.y = dataset_maps[mode] #x,y都是ndarray类型\n",
    "        self.x = torch.from_numpy(scaler.transform(self.x)).float() #from_numpy将NumPy数组转换成PyTorch张量\n",
    "        self.y = torch.from_numpy(self.y).float().reshape(-1, 1) #处理为多行1列的tensor类型,因为__getitem__切片时需要\n",
    "            \n",
    "    def __len__(self): #必须写\n",
    "        return len(self.x) #返回数据集的长度,0维的size\n",
    "    \n",
    "    def __getitem__(self, idx): #idx是索引，返回的是数据和标签，这里是一个样本\n",
    "        return self.x[idx], self.y[idx]\n",
    "    \n",
    "#train_ds是dataset类型的数据，与前面例子的FashionMNIST类型一致\n",
    "train_ds = HousingDataset(\"train\")\n",
    "valid_ds = HousingDataset(\"valid\")\n",
    "test_ds = HousingDataset(\"test\")"
   ],
   "outputs": [],
   "execution_count": 8
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-06T01:04:16.769517Z",
     "start_time": "2025-03-06T01:04:16.766597Z"
    }
   },
   "cell_type": "code",
   "source": "type(train_ds)",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "__main__.HousingDataset"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 9
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-06T01:04:16.778533Z",
     "start_time": "2025-03-06T01:04:16.770025Z"
    }
   },
   "source": "train_ds[1]",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(tensor([-0.2981,  0.3523, -0.1092, -0.2506, -0.0341, -0.0060,  1.0806, -1.0611]),\n",
       " tensor([1.5140]))"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 10
  },
  {
   "cell_type": "code",
   "source": [
    "train_ds[0][0]"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-03-06T01:04:16.784885Z",
     "start_time": "2025-03-06T01:04:16.778533Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([ 0.8015,  0.2722, -0.1162, -0.2023, -0.5431, -0.0210, -0.5898, -0.0824])"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 11
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### DataLoader"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-06T01:04:16.791483Z",
     "start_time": "2025-03-06T01:04:16.784885Z"
    }
   },
   "source": [
    "from torch.utils.data import DataLoader\n",
    "\n",
    "#放到DataLoader中的train_ds, valid_ds, test_ds都是dataset类型的数据\n",
    "batch_size = 16 #batch_size是可以调的超参数\n",
    "train_loader = DataLoader(train_ds, batch_size=batch_size, shuffle=True)\n",
    "val_loader = DataLoader(valid_ds, batch_size=batch_size, shuffle=False)\n",
    "test_loader = DataLoader(test_ds, batch_size=batch_size, shuffle=False)"
   ],
   "outputs": [],
   "execution_count": 12
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 定义模型"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-06T01:04:16.798221Z",
     "start_time": "2025-03-06T01:04:16.791483Z"
    }
   },
   "source": [
    "#回归模型我们只需要1个数\n",
    "\n",
    "class NeuralNetwork(nn.Module):\n",
    "    def __init__(self, input_dim=8):\n",
    "        super().__init__()\n",
    "        self.linear_relu_stack = nn.Sequential(\n",
    "            nn.Linear(input_dim, 30),\n",
    "            nn.ReLU(),\n",
    "            nn.Linear(30, 1)\n",
    "            )\n",
    "        \n",
    "    def forward(self, x):\n",
    "        # x.shape [batch size, 8]\n",
    "        logits = self.linear_relu_stack(x)\n",
    "        # logits.shape [batch size, 1]\n",
    "        return logits"
   ],
   "outputs": [],
   "execution_count": 13
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-06T01:04:16.804887Z",
     "start_time": "2025-03-06T01:04:16.799224Z"
    }
   },
   "cell_type": "code",
   "source": "8*30+30+30*1+1",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "301"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 14
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-06T01:04:16.810906Z",
     "start_time": "2025-03-06T01:04:16.804887Z"
    }
   },
   "source": [
    "class EarlyStopCallback:\n",
    "    def __init__(self, patience=5, min_delta=0.01):\n",
    "        \"\"\"\n",
    "\n",
    "        Args:\n",
    "            patience (int, optional): Number of epochs with no improvement after which training will be stopped.. Defaults to 5.\n",
    "            min_delta (float, optional): Minimum change in the monitored quantity to qualify as an improvement, i.e. an absolute \n",
    "                change of less than min_delta, will count as no improvement. Defaults to 0.01.\n",
    "        \"\"\"\n",
    "        self.patience = patience\n",
    "        self.min_delta = min_delta\n",
    "        self.best_metric = -1\n",
    "        self.counter = 0\n",
    "        \n",
    "    def __call__(self, metric):\n",
    "        if metric >= self.best_metric + self.min_delta:\n",
    "            # update best metric\n",
    "            self.best_metric = metric\n",
    "            # reset counter \n",
    "            self.counter = 0\n",
    "        else: \n",
    "            self.counter += 1\n",
    "            \n",
    "    @property\n",
    "    def early_stop(self):\n",
    "        return self.counter >= self.patience\n"
   ],
   "outputs": [],
   "execution_count": 15
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-06T01:04:16.816281Z",
     "start_time": "2025-03-06T01:04:16.810906Z"
    }
   },
   "source": [
    "from sklearn.metrics import accuracy_score\n",
    "\n",
    "@torch.no_grad()\n",
    "def evaluating(model, dataloader, loss_fct):\n",
    "    loss_list = []\n",
    "    for datas, labels in dataloader:\n",
    "        datas = datas.to(device)\n",
    "        labels = labels.to(device)\n",
    "        # 前向计算\n",
    "        logits = model(datas)\n",
    "        loss = loss_fct(logits, labels)         # 验证集损失\n",
    "        loss_list.append(loss.item())\n",
    "        \n",
    "    return np.mean(loss_list)\n"
   ],
   "outputs": [],
   "execution_count": 16
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-06T01:05:36.467662Z",
     "start_time": "2025-03-06T01:04:16.816281Z"
    }
   },
   "source": [
    "# 训练\n",
    "def training(\n",
    "    model, \n",
    "    train_loader, \n",
    "    val_loader, \n",
    "    epoch, \n",
    "    loss_fct, \n",
    "    optimizer,\n",
    "    early_stop_callback=None,\n",
    "    eval_step=500,\n",
    "    ):\n",
    "    record_dict = {\n",
    "        \"train\": [],\n",
    "        \"val\": []\n",
    "    }\n",
    "    \n",
    "    global_step = 0\n",
    "    model.train()\n",
    "    with tqdm(total=epoch * len(train_loader)) as pbar:\n",
    "        for epoch_id in range(epoch):\n",
    "            # training\n",
    "            for datas, labels in train_loader:#11610/16=726\n",
    "                datas = datas.to(device)\n",
    "                labels = labels.to(device)\n",
    "                # 梯度清空\n",
    "                optimizer.zero_grad()\n",
    "                # 模型前向计算\n",
    "                logits = model(datas) #得到预测值\n",
    "                # 计算损失\n",
    "                loss = loss_fct(logits, labels)\n",
    "                # 梯度回传\n",
    "                loss.backward()\n",
    "                # 调整优化器，包括学习率的变动等\n",
    "                optimizer.step()\n",
    " \n",
    "                loss = loss.cpu().item() #转为cpu类型，item()是取值\n",
    "                # record\n",
    "                \n",
    "                record_dict[\"train\"].append({\n",
    "                    \"loss\": loss, \"step\": global_step\n",
    "                })\n",
    "                \n",
    "                # evaluating\n",
    "                if global_step % eval_step == 0:\n",
    "                    model.eval()\n",
    "                    val_loss = evaluating(model, val_loader, loss_fct)\n",
    "                    record_dict[\"val\"].append({\n",
    "                        \"loss\": val_loss, \"step\": global_step\n",
    "                    })\n",
    "                    model.train()\n",
    "\n",
    "                    # 早停 Early Stop\n",
    "                    if early_stop_callback is not None:\n",
    "                        early_stop_callback(-val_loss) #根据验证集的损失来实现早停\n",
    "                        if early_stop_callback.early_stop:\n",
    "                            print(f\"Early stop at epoch {epoch_id} / global_step {global_step}\")\n",
    "                            return record_dict\n",
    "                    \n",
    "                # udate step\n",
    "                global_step += 1\n",
    "                pbar.update(1)\n",
    "                pbar.set_postfix({\"epoch\": epoch_id})\n",
    "        \n",
    "    return record_dict\n",
    "        \n",
    "\n",
    "epoch = 100\n",
    "\n",
    "model = NeuralNetwork()\n",
    "\n",
    "# 1. 定义损失函数 采用MSE损失,均方误差\n",
    "loss_fct = nn.MSELoss()\n",
    "# 2. 定义优化器 采用SGD\n",
    "# Optimizers specified in the torch.optim package\n",
    "optimizer = torch.optim.SGD(model.parameters(), lr=0.001, momentum=0.9)\n",
    "\n",
    "# 3. early stop\n",
    "early_stop_callback = EarlyStopCallback(patience=10, min_delta=1e-3)\n",
    "\n",
    "model = model.to(device)\n",
    "record = training(\n",
    "    model, \n",
    "    train_loader, \n",
    "    val_loader, \n",
    "    epoch, \n",
    "    loss_fct, \n",
    "    optimizer, \n",
    "    early_stop_callback=early_stop_callback,\n",
    "    eval_step=len(train_loader)\n",
    "    )"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "  0%|          | 0/72600 [00:00<?, ?it/s]"
      ],
      "application/vnd.jupyter.widget-view+json": {
       "version_major": 2,
       "version_minor": 0,
       "model_id": "138526bdfe2f4367a7c1f25c7c362400"
      }
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Early stop at epoch 66 / global_step 47916\n"
     ]
    }
   ],
   "execution_count": 17
  },
  {
   "cell_type": "code",
   "source": [
    "record"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-03-06T01:05:36.490214Z",
     "start_time": "2025-03-06T01:05:36.467662Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'train': [{'loss': 4.929024696350098, 'step': 0},\n",
       "  {'loss': 6.3610076904296875, 'step': 1},\n",
       "  {'loss': 6.508632659912109, 'step': 2},\n",
       "  {'loss': 4.985649108886719, 'step': 3},\n",
       "  {'loss': 5.282250881195068, 'step': 4},\n",
       "  {'loss': 5.215551376342773, 'step': 5},\n",
       "  {'loss': 4.5951690673828125, 'step': 6},\n",
       "  {'loss': 5.527980804443359, 'step': 7},\n",
       "  {'loss': 4.197072982788086, 'step': 8},\n",
       "  {'loss': 2.20096755027771, 'step': 9},\n",
       "  {'loss': 3.0457239151000977, 'step': 10},\n",
       "  {'loss': 3.4477298259735107, 'step': 11},\n",
       "  {'loss': 3.8128042221069336, 'step': 12},\n",
       "  {'loss': 3.6728761196136475, 'step': 13},\n",
       "  {'loss': 3.044346332550049, 'step': 14},\n",
       "  {'loss': 2.782076597213745, 'step': 15},\n",
       "  {'loss': 1.731018304824829, 'step': 16},\n",
       "  {'loss': 1.7049856185913086, 'step': 17},\n",
       "  {'loss': 1.121279239654541, 'step': 18},\n",
       "  {'loss': 2.301225185394287, 'step': 19},\n",
       "  {'loss': 1.776660680770874, 'step': 20},\n",
       "  {'loss': 0.4922794699668884, 'step': 21},\n",
       "  {'loss': 2.643444776535034, 'step': 22},\n",
       "  {'loss': 1.547092318534851, 'step': 23},\n",
       "  {'loss': 0.8841286897659302, 'step': 24},\n",
       "  {'loss': 0.5206591486930847, 'step': 25},\n",
       "  {'loss': 1.3316266536712646, 'step': 26},\n",
       "  {'loss': 1.134667158126831, 'step': 27},\n",
       "  {'loss': 0.8518675565719604, 'step': 28},\n",
       "  {'loss': 1.1121379137039185, 'step': 29},\n",
       "  {'loss': 1.634389877319336, 'step': 30},\n",
       "  {'loss': 1.3010581731796265, 'step': 31},\n",
       "  {'loss': 2.3356142044067383, 'step': 32},\n",
       "  {'loss': 0.9320818781852722, 'step': 33},\n",
       "  {'loss': 0.6129207015037537, 'step': 34},\n",
       "  {'loss': 1.0351539850234985, 'step': 35},\n",
       "  {'loss': 0.9587234258651733, 'step': 36},\n",
       "  {'loss': 0.7393152713775635, 'step': 37},\n",
       "  {'loss': 1.4381253719329834, 'step': 38},\n",
       "  {'loss': 0.8524332046508789, 'step': 39},\n",
       "  {'loss': 1.2390657663345337, 'step': 40},\n",
       "  {'loss': 0.9874202013015747, 'step': 41},\n",
       "  {'loss': 0.3964099586009979, 'step': 42},\n",
       "  {'loss': 1.7767655849456787, 'step': 43},\n",
       "  {'loss': 0.3606591820716858, 'step': 44},\n",
       "  {'loss': 0.9781002998352051, 'step': 45},\n",
       "  {'loss': 0.6597566604614258, 'step': 46},\n",
       "  {'loss': 0.6945757269859314, 'step': 47},\n",
       "  {'loss': 0.8104419708251953, 'step': 48},\n",
       "  {'loss': 0.8563311100006104, 'step': 49},\n",
       "  {'loss': 1.4215601682662964, 'step': 50},\n",
       "  {'loss': 0.9852316379547119, 'step': 51},\n",
       "  {'loss': 1.6189688444137573, 'step': 52},\n",
       "  {'loss': 1.4107518196105957, 'step': 53},\n",
       "  {'loss': 1.0605874061584473, 'step': 54},\n",
       "  {'loss': 0.9462398290634155, 'step': 55},\n",
       "  {'loss': 2.0882058143615723, 'step': 56},\n",
       "  {'loss': 0.8944492340087891, 'step': 57},\n",
       "  {'loss': 1.9978110790252686, 'step': 58},\n",
       "  {'loss': 0.40143129229545593, 'step': 59},\n",
       "  {'loss': 0.6003870964050293, 'step': 60},\n",
       "  {'loss': 0.7398377060890198, 'step': 61},\n",
       "  {'loss': 1.0102678537368774, 'step': 62},\n",
       "  {'loss': 0.5175949931144714, 'step': 63},\n",
       "  {'loss': 0.8703871369361877, 'step': 64},\n",
       "  {'loss': 2.6513752937316895, 'step': 65},\n",
       "  {'loss': 1.1717430353164673, 'step': 66},\n",
       "  {'loss': 0.5691744685173035, 'step': 67},\n",
       "  {'loss': 0.5994307994842529, 'step': 68},\n",
       "  {'loss': 0.692571222782135, 'step': 69},\n",
       "  {'loss': 0.45492151379585266, 'step': 70},\n",
       "  {'loss': 0.5899125337600708, 'step': 71},\n",
       "  {'loss': 0.40613916516304016, 'step': 72},\n",
       "  {'loss': 0.36171334981918335, 'step': 73},\n",
       "  {'loss': 0.651574432849884, 'step': 74},\n",
       "  {'loss': 1.0535024404525757, 'step': 75},\n",
       "  {'loss': 0.29048582911491394, 'step': 76},\n",
       "  {'loss': 0.9886966943740845, 'step': 77},\n",
       "  {'loss': 0.9949772357940674, 'step': 78},\n",
       "  {'loss': 1.111757755279541, 'step': 79},\n",
       "  {'loss': 0.23472987115383148, 'step': 80},\n",
       "  {'loss': 0.9862279891967773, 'step': 81},\n",
       "  {'loss': 1.5902462005615234, 'step': 82},\n",
       "  {'loss': 0.8103896379470825, 'step': 83},\n",
       "  {'loss': 0.8946630954742432, 'step': 84},\n",
       "  {'loss': 0.484198659658432, 'step': 85},\n",
       "  {'loss': 0.30664604902267456, 'step': 86},\n",
       "  {'loss': 0.5083590149879456, 'step': 87},\n",
       "  {'loss': 0.43052148818969727, 'step': 88},\n",
       "  {'loss': 0.672306478023529, 'step': 89},\n",
       "  {'loss': 0.6877907514572144, 'step': 90},\n",
       "  {'loss': 1.3189821243286133, 'step': 91},\n",
       "  {'loss': 0.23026293516159058, 'step': 92},\n",
       "  {'loss': 0.2975906729698181, 'step': 93},\n",
       "  {'loss': 1.0937016010284424, 'step': 94},\n",
       "  {'loss': 0.9842549562454224, 'step': 95},\n",
       "  {'loss': 1.0953365564346313, 'step': 96},\n",
       "  {'loss': 0.7406107783317566, 'step': 97},\n",
       "  {'loss': 0.6389669179916382, 'step': 98},\n",
       "  {'loss': 0.8315309882164001, 'step': 99},\n",
       "  {'loss': 1.1069039106369019, 'step': 100},\n",
       "  {'loss': 0.5262635350227356, 'step': 101},\n",
       "  {'loss': 0.41002705693244934, 'step': 102},\n",
       "  {'loss': 0.6852591037750244, 'step': 103},\n",
       "  {'loss': 0.5485935211181641, 'step': 104},\n",
       "  {'loss': 1.2383129596710205, 'step': 105},\n",
       "  {'loss': 0.2962384819984436, 'step': 106},\n",
       "  {'loss': 0.43815988302230835, 'step': 107},\n",
       "  {'loss': 0.7845057249069214, 'step': 108},\n",
       "  {'loss': 0.7960368394851685, 'step': 109},\n",
       "  {'loss': 2.929408311843872, 'step': 110},\n",
       "  {'loss': 1.0896302461624146, 'step': 111},\n",
       "  {'loss': 0.29638129472732544, 'step': 112},\n",
       "  {'loss': 1.1496838331222534, 'step': 113},\n",
       "  {'loss': 0.9001641273498535, 'step': 114},\n",
       "  {'loss': 0.6905590891838074, 'step': 115},\n",
       "  {'loss': 0.8522558212280273, 'step': 116},\n",
       "  {'loss': 0.6023369431495667, 'step': 117},\n",
       "  {'loss': 0.9374441504478455, 'step': 118},\n",
       "  {'loss': 0.4235258102416992, 'step': 119},\n",
       "  {'loss': 0.7260059118270874, 'step': 120},\n",
       "  {'loss': 0.6468716859817505, 'step': 121},\n",
       "  {'loss': 0.8445587158203125, 'step': 122},\n",
       "  {'loss': 0.7783163785934448, 'step': 123},\n",
       "  {'loss': 0.36022961139678955, 'step': 124},\n",
       "  {'loss': 1.1341675519943237, 'step': 125},\n",
       "  {'loss': 0.37086355686187744, 'step': 126},\n",
       "  {'loss': 0.6630738377571106, 'step': 127},\n",
       "  {'loss': 0.4926106929779053, 'step': 128},\n",
       "  {'loss': 0.4117757976055145, 'step': 129},\n",
       "  {'loss': 0.1561252921819687, 'step': 130},\n",
       "  {'loss': 1.1727420091629028, 'step': 131},\n",
       "  {'loss': 0.7227258682250977, 'step': 132},\n",
       "  {'loss': 0.6692628264427185, 'step': 133},\n",
       "  {'loss': 0.8520231246948242, 'step': 134},\n",
       "  {'loss': 0.7435005307197571, 'step': 135},\n",
       "  {'loss': 1.057661533355713, 'step': 136},\n",
       "  {'loss': 0.24174490571022034, 'step': 137},\n",
       "  {'loss': 0.606578528881073, 'step': 138},\n",
       "  {'loss': 0.7349281311035156, 'step': 139},\n",
       "  {'loss': 0.5035743713378906, 'step': 140},\n",
       "  {'loss': 0.7906543612480164, 'step': 141},\n",
       "  {'loss': 0.6766307353973389, 'step': 142},\n",
       "  {'loss': 0.44482195377349854, 'step': 143},\n",
       "  {'loss': 1.155176043510437, 'step': 144},\n",
       "  {'loss': 0.21529197692871094, 'step': 145},\n",
       "  {'loss': 0.7776504755020142, 'step': 146},\n",
       "  {'loss': 0.5618012547492981, 'step': 147},\n",
       "  {'loss': 0.7662113308906555, 'step': 148},\n",
       "  {'loss': 0.9577324986457825, 'step': 149},\n",
       "  {'loss': 0.6891430020332336, 'step': 150},\n",
       "  {'loss': 1.5516977310180664, 'step': 151},\n",
       "  {'loss': 0.6841186285018921, 'step': 152},\n",
       "  {'loss': 0.8192423582077026, 'step': 153},\n",
       "  {'loss': 1.5286164283752441, 'step': 154},\n",
       "  {'loss': 0.3353579640388489, 'step': 155},\n",
       "  {'loss': 1.1872148513793945, 'step': 156},\n",
       "  {'loss': 1.4079482555389404, 'step': 157},\n",
       "  {'loss': 0.8845841884613037, 'step': 158},\n",
       "  {'loss': 0.3691844940185547, 'step': 159},\n",
       "  {'loss': 0.5370381474494934, 'step': 160},\n",
       "  {'loss': 0.7288820147514343, 'step': 161},\n",
       "  {'loss': 0.5777508020401001, 'step': 162},\n",
       "  {'loss': 0.938995361328125, 'step': 163},\n",
       "  {'loss': 0.4640975296497345, 'step': 164},\n",
       "  {'loss': 0.47673675417900085, 'step': 165},\n",
       "  {'loss': 0.527901291847229, 'step': 166},\n",
       "  {'loss': 0.6780548095703125, 'step': 167},\n",
       "  {'loss': 0.19126860797405243, 'step': 168},\n",
       "  {'loss': 0.9829151630401611, 'step': 169},\n",
       "  {'loss': 0.3050808906555176, 'step': 170},\n",
       "  {'loss': 0.5553807020187378, 'step': 171},\n",
       "  {'loss': 0.5371741652488708, 'step': 172},\n",
       "  {'loss': 1.4530830383300781, 'step': 173},\n",
       "  {'loss': 1.6606721878051758, 'step': 174},\n",
       "  {'loss': 1.3387993574142456, 'step': 175},\n",
       "  {'loss': 0.5162820816040039, 'step': 176},\n",
       "  {'loss': 0.7290146350860596, 'step': 177},\n",
       "  {'loss': 0.7208064198493958, 'step': 178},\n",
       "  {'loss': 1.279630184173584, 'step': 179},\n",
       "  {'loss': 0.30203256011009216, 'step': 180},\n",
       "  {'loss': 1.132440447807312, 'step': 181},\n",
       "  {'loss': 0.8404980897903442, 'step': 182},\n",
       "  {'loss': 0.4697827100753784, 'step': 183},\n",
       "  {'loss': 0.5245559215545654, 'step': 184},\n",
       "  {'loss': 0.4351974427700043, 'step': 185},\n",
       "  {'loss': 0.4387268126010895, 'step': 186},\n",
       "  {'loss': 0.4932815432548523, 'step': 187},\n",
       "  {'loss': 0.8103504776954651, 'step': 188},\n",
       "  {'loss': 0.4678356647491455, 'step': 189},\n",
       "  {'loss': 1.1268620491027832, 'step': 190},\n",
       "  {'loss': 0.31692805886268616, 'step': 191},\n",
       "  {'loss': 0.3776894211769104, 'step': 192},\n",
       "  {'loss': 0.7897424697875977, 'step': 193},\n",
       "  {'loss': 0.7672717571258545, 'step': 194},\n",
       "  {'loss': 0.7987155914306641, 'step': 195},\n",
       "  {'loss': 0.7300949096679688, 'step': 196},\n",
       "  {'loss': 0.30327108502388, 'step': 197},\n",
       "  {'loss': 0.144007608294487, 'step': 198},\n",
       "  {'loss': 0.48416149616241455, 'step': 199},\n",
       "  {'loss': 0.34979668259620667, 'step': 200},\n",
       "  {'loss': 0.13239359855651855, 'step': 201},\n",
       "  {'loss': 0.707614004611969, 'step': 202},\n",
       "  {'loss': 0.9791157841682434, 'step': 203},\n",
       "  {'loss': 0.280274897813797, 'step': 204},\n",
       "  {'loss': 0.531696617603302, 'step': 205},\n",
       "  {'loss': 1.1686396598815918, 'step': 206},\n",
       "  {'loss': 0.6383435130119324, 'step': 207},\n",
       "  {'loss': 0.49889492988586426, 'step': 208},\n",
       "  {'loss': 1.487892985343933, 'step': 209},\n",
       "  {'loss': 0.3759342432022095, 'step': 210},\n",
       "  {'loss': 0.7159421443939209, 'step': 211},\n",
       "  {'loss': 0.4392130970954895, 'step': 212},\n",
       "  {'loss': 0.553321123123169, 'step': 213},\n",
       "  {'loss': 0.8291913866996765, 'step': 214},\n",
       "  {'loss': 3.1400375366210938, 'step': 215},\n",
       "  {'loss': 0.6015669703483582, 'step': 216},\n",
       "  {'loss': 0.5650870203971863, 'step': 217},\n",
       "  {'loss': 0.7831299901008606, 'step': 218},\n",
       "  {'loss': 0.2829258441925049, 'step': 219},\n",
       "  {'loss': 0.636766791343689, 'step': 220},\n",
       "  {'loss': 0.3497842252254486, 'step': 221},\n",
       "  {'loss': 0.34479576349258423, 'step': 222},\n",
       "  {'loss': 0.30954936146736145, 'step': 223},\n",
       "  {'loss': 0.6917450428009033, 'step': 224},\n",
       "  {'loss': 0.5580110549926758, 'step': 225},\n",
       "  {'loss': 0.9250614643096924, 'step': 226},\n",
       "  {'loss': 0.41070276498794556, 'step': 227},\n",
       "  {'loss': 0.35927054286003113, 'step': 228},\n",
       "  {'loss': 0.3273102641105652, 'step': 229},\n",
       "  {'loss': 1.8892295360565186, 'step': 230},\n",
       "  {'loss': 0.40143343806266785, 'step': 231},\n",
       "  {'loss': 0.2177756130695343, 'step': 232},\n",
       "  {'loss': 0.4093751311302185, 'step': 233},\n",
       "  {'loss': 0.7700578570365906, 'step': 234},\n",
       "  {'loss': 0.17114226520061493, 'step': 235},\n",
       "  {'loss': 0.2773287892341614, 'step': 236},\n",
       "  {'loss': 0.29317283630371094, 'step': 237},\n",
       "  {'loss': 0.15788866579532623, 'step': 238},\n",
       "  {'loss': 0.6056778430938721, 'step': 239},\n",
       "  {'loss': 0.22381193935871124, 'step': 240},\n",
       "  {'loss': 0.52041095495224, 'step': 241},\n",
       "  {'loss': 0.2219579517841339, 'step': 242},\n",
       "  {'loss': 0.6621094942092896, 'step': 243},\n",
       "  {'loss': 1.6548042297363281, 'step': 244},\n",
       "  {'loss': 0.20384569466114044, 'step': 245},\n",
       "  {'loss': 0.30519747734069824, 'step': 246},\n",
       "  {'loss': 0.2783459424972534, 'step': 247},\n",
       "  {'loss': 0.22671258449554443, 'step': 248},\n",
       "  {'loss': 1.3945834636688232, 'step': 249},\n",
       "  {'loss': 0.6266763806343079, 'step': 250},\n",
       "  {'loss': 0.913564920425415, 'step': 251},\n",
       "  {'loss': 1.3110363483428955, 'step': 252},\n",
       "  {'loss': 0.4807649254798889, 'step': 253},\n",
       "  {'loss': 0.366971492767334, 'step': 254},\n",
       "  {'loss': 0.304323673248291, 'step': 255},\n",
       "  {'loss': 0.6481634974479675, 'step': 256},\n",
       "  {'loss': 0.6109568476676941, 'step': 257},\n",
       "  {'loss': 0.4264845550060272, 'step': 258},\n",
       "  {'loss': 0.6287363767623901, 'step': 259},\n",
       "  {'loss': 0.5647563338279724, 'step': 260},\n",
       "  {'loss': 0.2649720311164856, 'step': 261},\n",
       "  {'loss': 0.7607041001319885, 'step': 262},\n",
       "  {'loss': 0.3772689402103424, 'step': 263},\n",
       "  {'loss': 1.107803463935852, 'step': 264},\n",
       "  {'loss': 0.17926177382469177, 'step': 265},\n",
       "  {'loss': 0.6669294834136963, 'step': 266},\n",
       "  {'loss': 0.745520830154419, 'step': 267},\n",
       "  {'loss': 0.8912676572799683, 'step': 268},\n",
       "  {'loss': 1.6814814805984497, 'step': 269},\n",
       "  {'loss': 0.5185040235519409, 'step': 270},\n",
       "  {'loss': 0.3533584475517273, 'step': 271},\n",
       "  {'loss': 0.5538548231124878, 'step': 272},\n",
       "  {'loss': 0.4217457175254822, 'step': 273},\n",
       "  {'loss': 0.4988170862197876, 'step': 274},\n",
       "  {'loss': 0.24028901755809784, 'step': 275},\n",
       "  {'loss': 0.0923338383436203, 'step': 276},\n",
       "  {'loss': 0.3543573021888733, 'step': 277},\n",
       "  {'loss': 0.8008000254631042, 'step': 278},\n",
       "  {'loss': 1.2014352083206177, 'step': 279},\n",
       "  {'loss': 0.7851522564888, 'step': 280},\n",
       "  {'loss': 0.28560349345207214, 'step': 281},\n",
       "  {'loss': 0.5451475381851196, 'step': 282},\n",
       "  {'loss': 0.21876882016658783, 'step': 283},\n",
       "  {'loss': 0.6079142093658447, 'step': 284},\n",
       "  {'loss': 0.5107249021530151, 'step': 285},\n",
       "  {'loss': 0.35959672927856445, 'step': 286},\n",
       "  {'loss': 0.2231256365776062, 'step': 287},\n",
       "  {'loss': 0.6002985835075378, 'step': 288},\n",
       "  {'loss': 0.595802903175354, 'step': 289},\n",
       "  {'loss': 0.9440559148788452, 'step': 290},\n",
       "  {'loss': 0.39436525106430054, 'step': 291},\n",
       "  {'loss': 0.6310628652572632, 'step': 292},\n",
       "  {'loss': 0.6006138324737549, 'step': 293},\n",
       "  {'loss': 0.8275907635688782, 'step': 294},\n",
       "  {'loss': 0.6159723997116089, 'step': 295},\n",
       "  {'loss': 0.36138904094696045, 'step': 296},\n",
       "  {'loss': 0.9630841612815857, 'step': 297},\n",
       "  {'loss': 0.34118330478668213, 'step': 298},\n",
       "  {'loss': 0.2666528820991516, 'step': 299},\n",
       "  {'loss': 0.2434503734111786, 'step': 300},\n",
       "  {'loss': 0.15969982743263245, 'step': 301},\n",
       "  {'loss': 0.45156294107437134, 'step': 302},\n",
       "  {'loss': 0.3619823753833771, 'step': 303},\n",
       "  {'loss': 0.5262985229492188, 'step': 304},\n",
       "  {'loss': 0.510479211807251, 'step': 305},\n",
       "  {'loss': 0.7616865038871765, 'step': 306},\n",
       "  {'loss': 0.28657934069633484, 'step': 307},\n",
       "  {'loss': 0.3037458062171936, 'step': 308},\n",
       "  {'loss': 0.27778732776641846, 'step': 309},\n",
       "  {'loss': 0.5359677672386169, 'step': 310},\n",
       "  {'loss': 0.43538546562194824, 'step': 311},\n",
       "  {'loss': 0.2722543478012085, 'step': 312},\n",
       "  {'loss': 0.5093300342559814, 'step': 313},\n",
       "  {'loss': 0.7005472183227539, 'step': 314},\n",
       "  {'loss': 0.696956992149353, 'step': 315},\n",
       "  {'loss': 0.4471505284309387, 'step': 316},\n",
       "  {'loss': 0.25932788848876953, 'step': 317},\n",
       "  {'loss': 0.7084880471229553, 'step': 318},\n",
       "  {'loss': 1.021480917930603, 'step': 319},\n",
       "  {'loss': 0.1573077291250229, 'step': 320},\n",
       "  {'loss': 0.5423497557640076, 'step': 321},\n",
       "  {'loss': 0.3131293058395386, 'step': 322},\n",
       "  {'loss': 0.3314392566680908, 'step': 323},\n",
       "  {'loss': 0.8758137226104736, 'step': 324},\n",
       "  {'loss': 0.36661994457244873, 'step': 325},\n",
       "  {'loss': 0.455424964427948, 'step': 326},\n",
       "  {'loss': 0.20782971382141113, 'step': 327},\n",
       "  {'loss': 0.3336412012577057, 'step': 328},\n",
       "  {'loss': 0.3859025835990906, 'step': 329},\n",
       "  {'loss': 0.3671204447746277, 'step': 330},\n",
       "  {'loss': 0.2993520498275757, 'step': 331},\n",
       "  {'loss': 0.6280366778373718, 'step': 332},\n",
       "  {'loss': 0.33300289511680603, 'step': 333},\n",
       "  {'loss': 0.42616701126098633, 'step': 334},\n",
       "  {'loss': 1.3162232637405396, 'step': 335},\n",
       "  {'loss': 0.3756283223628998, 'step': 336},\n",
       "  {'loss': 0.26574844121932983, 'step': 337},\n",
       "  {'loss': 0.38953855633735657, 'step': 338},\n",
       "  {'loss': 0.43011152744293213, 'step': 339},\n",
       "  {'loss': 0.49052637815475464, 'step': 340},\n",
       "  {'loss': 0.220718115568161, 'step': 341},\n",
       "  {'loss': 0.4695916771888733, 'step': 342},\n",
       "  {'loss': 0.33708032965660095, 'step': 343},\n",
       "  {'loss': 0.2940780520439148, 'step': 344},\n",
       "  {'loss': 0.7429128289222717, 'step': 345},\n",
       "  {'loss': 0.36182862520217896, 'step': 346},\n",
       "  {'loss': 0.39250653982162476, 'step': 347},\n",
       "  {'loss': 0.8340349197387695, 'step': 348},\n",
       "  {'loss': 0.2516721785068512, 'step': 349},\n",
       "  {'loss': 0.7580292224884033, 'step': 350},\n",
       "  {'loss': 1.3363953828811646, 'step': 351},\n",
       "  {'loss': 0.27364683151245117, 'step': 352},\n",
       "  {'loss': 0.3889044523239136, 'step': 353},\n",
       "  {'loss': 0.2006092369556427, 'step': 354},\n",
       "  {'loss': 0.6461303234100342, 'step': 355},\n",
       "  {'loss': 0.5379794239997864, 'step': 356},\n",
       "  {'loss': 0.6866219639778137, 'step': 357},\n",
       "  {'loss': 0.7707279324531555, 'step': 358},\n",
       "  {'loss': 0.6433281898498535, 'step': 359},\n",
       "  {'loss': 0.35997241735458374, 'step': 360},\n",
       "  {'loss': 0.432095468044281, 'step': 361},\n",
       "  {'loss': 0.676467776298523, 'step': 362},\n",
       "  {'loss': 0.5491786599159241, 'step': 363},\n",
       "  {'loss': 0.6051902174949646, 'step': 364},\n",
       "  {'loss': 0.5354202389717102, 'step': 365},\n",
       "  {'loss': 0.6962727308273315, 'step': 366},\n",
       "  {'loss': 1.0320333242416382, 'step': 367},\n",
       "  {'loss': 0.6829409599304199, 'step': 368},\n",
       "  {'loss': 0.8789558410644531, 'step': 369},\n",
       "  {'loss': 0.9123833179473877, 'step': 370},\n",
       "  {'loss': 1.052132248878479, 'step': 371},\n",
       "  {'loss': 0.3411492109298706, 'step': 372},\n",
       "  {'loss': 0.34616619348526, 'step': 373},\n",
       "  {'loss': 0.238466277718544, 'step': 374},\n",
       "  {'loss': 0.31763744354248047, 'step': 375},\n",
       "  {'loss': 0.6400362253189087, 'step': 376},\n",
       "  {'loss': 0.4146633744239807, 'step': 377},\n",
       "  {'loss': 0.1561216115951538, 'step': 378},\n",
       "  {'loss': 0.3052304983139038, 'step': 379},\n",
       "  {'loss': 1.1015021800994873, 'step': 380},\n",
       "  {'loss': 0.6347739696502686, 'step': 381},\n",
       "  {'loss': 0.8835065364837646, 'step': 382},\n",
       "  {'loss': 0.6863833665847778, 'step': 383},\n",
       "  {'loss': 0.11959502100944519, 'step': 384},\n",
       "  {'loss': 0.9909132719039917, 'step': 385},\n",
       "  {'loss': 0.6981701254844666, 'step': 386},\n",
       "  {'loss': 0.5620236396789551, 'step': 387},\n",
       "  {'loss': 0.17315296828746796, 'step': 388},\n",
       "  {'loss': 0.4764350652694702, 'step': 389},\n",
       "  {'loss': 1.1007007360458374, 'step': 390},\n",
       "  {'loss': 0.5738511085510254, 'step': 391},\n",
       "  {'loss': 1.0252532958984375, 'step': 392},\n",
       "  {'loss': 0.8991883397102356, 'step': 393},\n",
       "  {'loss': 0.8340513706207275, 'step': 394},\n",
       "  {'loss': 0.49473413825035095, 'step': 395},\n",
       "  {'loss': 0.6656574010848999, 'step': 396},\n",
       "  {'loss': 0.3135223984718323, 'step': 397},\n",
       "  {'loss': 1.5695959329605103, 'step': 398},\n",
       "  {'loss': 0.704896092414856, 'step': 399},\n",
       "  {'loss': 0.3711197078227997, 'step': 400},\n",
       "  {'loss': 1.1008384227752686, 'step': 401},\n",
       "  {'loss': 0.15280306339263916, 'step': 402},\n",
       "  {'loss': 0.11301290988922119, 'step': 403},\n",
       "  {'loss': 0.3628207743167877, 'step': 404},\n",
       "  {'loss': 0.4510144889354706, 'step': 405},\n",
       "  {'loss': 0.4632706642150879, 'step': 406},\n",
       "  {'loss': 0.31722646951675415, 'step': 407},\n",
       "  {'loss': 0.42051106691360474, 'step': 408},\n",
       "  {'loss': 0.630891740322113, 'step': 409},\n",
       "  {'loss': 0.35825541615486145, 'step': 410},\n",
       "  {'loss': 0.42466801404953003, 'step': 411},\n",
       "  {'loss': 0.8383941650390625, 'step': 412},\n",
       "  {'loss': 0.8617713451385498, 'step': 413},\n",
       "  {'loss': 0.3281203508377075, 'step': 414},\n",
       "  {'loss': 0.28249889612197876, 'step': 415},\n",
       "  {'loss': 0.7770489454269409, 'step': 416},\n",
       "  {'loss': 0.21419024467468262, 'step': 417},\n",
       "  {'loss': 0.3336312770843506, 'step': 418},\n",
       "  {'loss': 0.466913640499115, 'step': 419},\n",
       "  {'loss': 0.38858139514923096, 'step': 420},\n",
       "  {'loss': 0.5310503244400024, 'step': 421},\n",
       "  {'loss': 0.43261176347732544, 'step': 422},\n",
       "  {'loss': 0.9705795645713806, 'step': 423},\n",
       "  {'loss': 0.18116822838783264, 'step': 424},\n",
       "  {'loss': 1.0780810117721558, 'step': 425},\n",
       "  {'loss': 0.4910616874694824, 'step': 426},\n",
       "  {'loss': 0.5406052470207214, 'step': 427},\n",
       "  {'loss': 0.2801758348941803, 'step': 428},\n",
       "  {'loss': 0.5417383909225464, 'step': 429},\n",
       "  {'loss': 1.0595401525497437, 'step': 430},\n",
       "  {'loss': 0.38875406980514526, 'step': 431},\n",
       "  {'loss': 0.18638145923614502, 'step': 432},\n",
       "  {'loss': 0.7352761626243591, 'step': 433},\n",
       "  {'loss': 0.8095976710319519, 'step': 434},\n",
       "  {'loss': 0.2014128565788269, 'step': 435},\n",
       "  {'loss': 0.542696475982666, 'step': 436},\n",
       "  {'loss': 0.19757261872291565, 'step': 437},\n",
       "  {'loss': 0.5345211029052734, 'step': 438},\n",
       "  {'loss': 0.13644713163375854, 'step': 439},\n",
       "  {'loss': 0.9040692448616028, 'step': 440},\n",
       "  {'loss': 0.19918586313724518, 'step': 441},\n",
       "  {'loss': 0.5029677152633667, 'step': 442},\n",
       "  {'loss': 0.17914843559265137, 'step': 443},\n",
       "  {'loss': 0.7121463418006897, 'step': 444},\n",
       "  {'loss': 0.17827150225639343, 'step': 445},\n",
       "  {'loss': 0.18432390689849854, 'step': 446},\n",
       "  {'loss': 1.5733009576797485, 'step': 447},\n",
       "  {'loss': 0.5433705449104309, 'step': 448},\n",
       "  {'loss': 0.32344669103622437, 'step': 449},\n",
       "  {'loss': 0.7215337753295898, 'step': 450},\n",
       "  {'loss': 0.8008942008018494, 'step': 451},\n",
       "  {'loss': 0.401383638381958, 'step': 452},\n",
       "  {'loss': 0.3658798336982727, 'step': 453},\n",
       "  {'loss': 0.6070674657821655, 'step': 454},\n",
       "  {'loss': 0.3402329385280609, 'step': 455},\n",
       "  {'loss': 0.803044319152832, 'step': 456},\n",
       "  {'loss': 0.6245443224906921, 'step': 457},\n",
       "  {'loss': 0.5035508275032043, 'step': 458},\n",
       "  {'loss': 0.4608883559703827, 'step': 459},\n",
       "  {'loss': 0.9241689443588257, 'step': 460},\n",
       "  {'loss': 0.31714192032814026, 'step': 461},\n",
       "  {'loss': 0.14962166547775269, 'step': 462},\n",
       "  {'loss': 0.4992568790912628, 'step': 463},\n",
       "  {'loss': 0.3906402587890625, 'step': 464},\n",
       "  {'loss': 0.17575742304325104, 'step': 465},\n",
       "  {'loss': 0.7291422486305237, 'step': 466},\n",
       "  {'loss': 0.20159240067005157, 'step': 467},\n",
       "  {'loss': 0.44246906042099, 'step': 468},\n",
       "  {'loss': 0.5271759033203125, 'step': 469},\n",
       "  {'loss': 0.36084532737731934, 'step': 470},\n",
       "  {'loss': 0.4875281751155853, 'step': 471},\n",
       "  {'loss': 0.5162830948829651, 'step': 472},\n",
       "  {'loss': 0.5923086404800415, 'step': 473},\n",
       "  {'loss': 0.4864615201950073, 'step': 474},\n",
       "  {'loss': 0.781058669090271, 'step': 475},\n",
       "  {'loss': 0.33184105157852173, 'step': 476},\n",
       "  {'loss': 0.613292396068573, 'step': 477},\n",
       "  {'loss': 0.35360002517700195, 'step': 478},\n",
       "  {'loss': 0.19846899807453156, 'step': 479},\n",
       "  {'loss': 0.27191200852394104, 'step': 480},\n",
       "  {'loss': 0.3526368737220764, 'step': 481},\n",
       "  {'loss': 0.8342458009719849, 'step': 482},\n",
       "  {'loss': 0.5342874526977539, 'step': 483},\n",
       "  {'loss': 0.2805541157722473, 'step': 484},\n",
       "  {'loss': 0.3697410821914673, 'step': 485},\n",
       "  {'loss': 0.1991688311100006, 'step': 486},\n",
       "  {'loss': 0.2783646881580353, 'step': 487},\n",
       "  {'loss': 0.4939274787902832, 'step': 488},\n",
       "  {'loss': 0.32347601652145386, 'step': 489},\n",
       "  {'loss': 0.3810124099254608, 'step': 490},\n",
       "  {'loss': 0.19669830799102783, 'step': 491},\n",
       "  {'loss': 0.5579732656478882, 'step': 492},\n",
       "  {'loss': 0.2326410412788391, 'step': 493},\n",
       "  {'loss': 0.3407776653766632, 'step': 494},\n",
       "  {'loss': 1.4411594867706299, 'step': 495},\n",
       "  {'loss': 0.7327306866645813, 'step': 496},\n",
       "  {'loss': 0.22295516729354858, 'step': 497},\n",
       "  {'loss': 0.3991807699203491, 'step': 498},\n",
       "  {'loss': 0.39230358600616455, 'step': 499},\n",
       "  {'loss': 0.961409330368042, 'step': 500},\n",
       "  {'loss': 0.6525282859802246, 'step': 501},\n",
       "  {'loss': 0.326838880777359, 'step': 502},\n",
       "  {'loss': 0.4311089515686035, 'step': 503},\n",
       "  {'loss': 0.5980753898620605, 'step': 504},\n",
       "  {'loss': 0.43052297830581665, 'step': 505},\n",
       "  {'loss': 0.36733925342559814, 'step': 506},\n",
       "  {'loss': 0.6491612792015076, 'step': 507},\n",
       "  {'loss': 0.5001344680786133, 'step': 508},\n",
       "  {'loss': 0.6831703186035156, 'step': 509},\n",
       "  {'loss': 0.25893157720565796, 'step': 510},\n",
       "  {'loss': 0.1765720546245575, 'step': 511},\n",
       "  {'loss': 0.33370542526245117, 'step': 512},\n",
       "  {'loss': 0.5554848313331604, 'step': 513},\n",
       "  {'loss': 0.4991514980792999, 'step': 514},\n",
       "  {'loss': 0.8128412365913391, 'step': 515},\n",
       "  {'loss': 0.9223099946975708, 'step': 516},\n",
       "  {'loss': 0.3248686194419861, 'step': 517},\n",
       "  {'loss': 0.7646716833114624, 'step': 518},\n",
       "  {'loss': 0.36683955788612366, 'step': 519},\n",
       "  {'loss': 0.875149130821228, 'step': 520},\n",
       "  {'loss': 0.8615512251853943, 'step': 521},\n",
       "  {'loss': 0.6507010459899902, 'step': 522},\n",
       "  {'loss': 0.08884570002555847, 'step': 523},\n",
       "  {'loss': 0.20823119580745697, 'step': 524},\n",
       "  {'loss': 1.1269522905349731, 'step': 525},\n",
       "  {'loss': 0.7911955118179321, 'step': 526},\n",
       "  {'loss': 0.12136948853731155, 'step': 527},\n",
       "  {'loss': 0.29655951261520386, 'step': 528},\n",
       "  {'loss': 0.36081475019454956, 'step': 529},\n",
       "  {'loss': 0.7354851961135864, 'step': 530},\n",
       "  {'loss': 0.7227422595024109, 'step': 531},\n",
       "  {'loss': 0.5272927284240723, 'step': 532},\n",
       "  {'loss': 0.690585732460022, 'step': 533},\n",
       "  {'loss': 0.1784602850675583, 'step': 534},\n",
       "  {'loss': 1.0687862634658813, 'step': 535},\n",
       "  {'loss': 0.4965532422065735, 'step': 536},\n",
       "  {'loss': 0.6700844764709473, 'step': 537},\n",
       "  {'loss': 1.089481234550476, 'step': 538},\n",
       "  {'loss': 0.5562443137168884, 'step': 539},\n",
       "  {'loss': 0.40968817472457886, 'step': 540},\n",
       "  {'loss': 0.2913443446159363, 'step': 541},\n",
       "  {'loss': 0.7835029363632202, 'step': 542},\n",
       "  {'loss': 0.38385194540023804, 'step': 543},\n",
       "  {'loss': 2.0197789669036865, 'step': 544},\n",
       "  {'loss': 0.5059794187545776, 'step': 545},\n",
       "  {'loss': 0.7558884024620056, 'step': 546},\n",
       "  {'loss': 0.5153319239616394, 'step': 547},\n",
       "  {'loss': 0.547924816608429, 'step': 548},\n",
       "  {'loss': 0.8710432052612305, 'step': 549},\n",
       "  {'loss': 0.8508651852607727, 'step': 550},\n",
       "  {'loss': 0.5429442524909973, 'step': 551},\n",
       "  {'loss': 0.38372328877449036, 'step': 552},\n",
       "  {'loss': 0.2981660068035126, 'step': 553},\n",
       "  {'loss': 0.32264259457588196, 'step': 554},\n",
       "  {'loss': 0.2163921743631363, 'step': 555},\n",
       "  {'loss': 1.422082781791687, 'step': 556},\n",
       "  {'loss': 0.4241122305393219, 'step': 557},\n",
       "  {'loss': 0.2961985170841217, 'step': 558},\n",
       "  {'loss': 0.1319446712732315, 'step': 559},\n",
       "  {'loss': 0.20412138104438782, 'step': 560},\n",
       "  {'loss': 0.6112866401672363, 'step': 561},\n",
       "  {'loss': 0.29141440987586975, 'step': 562},\n",
       "  {'loss': 0.24580718576908112, 'step': 563},\n",
       "  {'loss': 0.30969470739364624, 'step': 564},\n",
       "  {'loss': 0.11991465091705322, 'step': 565},\n",
       "  {'loss': 0.5207563042640686, 'step': 566},\n",
       "  {'loss': 0.4085637927055359, 'step': 567},\n",
       "  {'loss': 0.17741021513938904, 'step': 568},\n",
       "  {'loss': 0.33113348484039307, 'step': 569},\n",
       "  {'loss': 0.2343733012676239, 'step': 570},\n",
       "  {'loss': 0.8272619843482971, 'step': 571},\n",
       "  {'loss': 0.5535153150558472, 'step': 572},\n",
       "  {'loss': 0.6424596905708313, 'step': 573},\n",
       "  {'loss': 0.47830596566200256, 'step': 574},\n",
       "  {'loss': 0.9197044968605042, 'step': 575},\n",
       "  {'loss': 0.41251102089881897, 'step': 576},\n",
       "  {'loss': 0.6473856568336487, 'step': 577},\n",
       "  {'loss': 0.2639918327331543, 'step': 578},\n",
       "  {'loss': 0.14797140657901764, 'step': 579},\n",
       "  {'loss': 0.6844649910926819, 'step': 580},\n",
       "  {'loss': 0.3388577699661255, 'step': 581},\n",
       "  {'loss': 0.5588626861572266, 'step': 582},\n",
       "  {'loss': 0.1434732973575592, 'step': 583},\n",
       "  {'loss': 0.762139081954956, 'step': 584},\n",
       "  {'loss': 0.308682918548584, 'step': 585},\n",
       "  {'loss': 0.50738525390625, 'step': 586},\n",
       "  {'loss': 0.45867425203323364, 'step': 587},\n",
       "  {'loss': 0.4056549370288849, 'step': 588},\n",
       "  {'loss': 0.3475987911224365, 'step': 589},\n",
       "  {'loss': 13.661520004272461, 'step': 590},\n",
       "  {'loss': 0.2513778805732727, 'step': 591},\n",
       "  {'loss': 0.22751818597316742, 'step': 592},\n",
       "  {'loss': 0.24344873428344727, 'step': 593},\n",
       "  {'loss': 0.2893105745315552, 'step': 594},\n",
       "  {'loss': 0.7076735496520996, 'step': 595},\n",
       "  {'loss': 0.5164110660552979, 'step': 596},\n",
       "  {'loss': 0.3694196939468384, 'step': 597},\n",
       "  {'loss': 0.5379949808120728, 'step': 598},\n",
       "  {'loss': 0.3631531000137329, 'step': 599},\n",
       "  {'loss': 0.6330990791320801, 'step': 600},\n",
       "  {'loss': 0.2614259719848633, 'step': 601},\n",
       "  {'loss': 0.6263765096664429, 'step': 602},\n",
       "  {'loss': 0.6376842856407166, 'step': 603},\n",
       "  {'loss': 0.991110622882843, 'step': 604},\n",
       "  {'loss': 0.6522578001022339, 'step': 605},\n",
       "  {'loss': 0.41443806886672974, 'step': 606},\n",
       "  {'loss': 0.3872067332267761, 'step': 607},\n",
       "  {'loss': 0.8085741400718689, 'step': 608},\n",
       "  {'loss': 0.8733590841293335, 'step': 609},\n",
       "  {'loss': 0.22488845884799957, 'step': 610},\n",
       "  {'loss': 0.22699636220932007, 'step': 611},\n",
       "  {'loss': 0.8208633065223694, 'step': 612},\n",
       "  {'loss': 0.7985491752624512, 'step': 613},\n",
       "  {'loss': 0.7224377989768982, 'step': 614},\n",
       "  {'loss': 0.5583152770996094, 'step': 615},\n",
       "  {'loss': 0.5033197402954102, 'step': 616},\n",
       "  {'loss': 0.3733549118041992, 'step': 617},\n",
       "  {'loss': 0.9089300036430359, 'step': 618},\n",
       "  {'loss': 0.4549369513988495, 'step': 619},\n",
       "  {'loss': 0.2741764783859253, 'step': 620},\n",
       "  {'loss': 0.3918497562408447, 'step': 621},\n",
       "  {'loss': 0.9938408136367798, 'step': 622},\n",
       "  {'loss': 0.890306830406189, 'step': 623},\n",
       "  {'loss': 0.49632009863853455, 'step': 624},\n",
       "  {'loss': 0.4964427947998047, 'step': 625},\n",
       "  {'loss': 0.15888717770576477, 'step': 626},\n",
       "  {'loss': 0.8465996980667114, 'step': 627},\n",
       "  {'loss': 0.14399558305740356, 'step': 628},\n",
       "  {'loss': 0.3228437006473541, 'step': 629},\n",
       "  {'loss': 0.22686508297920227, 'step': 630},\n",
       "  {'loss': 0.21398982405662537, 'step': 631},\n",
       "  {'loss': 0.7285810708999634, 'step': 632},\n",
       "  {'loss': 0.3033497631549835, 'step': 633},\n",
       "  {'loss': 0.35011714696884155, 'step': 634},\n",
       "  {'loss': 0.6050869822502136, 'step': 635},\n",
       "  {'loss': 0.384792685508728, 'step': 636},\n",
       "  {'loss': 0.3669157922267914, 'step': 637},\n",
       "  {'loss': 0.38873928785324097, 'step': 638},\n",
       "  {'loss': 0.1613270342350006, 'step': 639},\n",
       "  {'loss': 0.14890171587467194, 'step': 640},\n",
       "  {'loss': 0.5441074371337891, 'step': 641},\n",
       "  {'loss': 0.1722376048564911, 'step': 642},\n",
       "  {'loss': 0.7892756462097168, 'step': 643},\n",
       "  {'loss': 0.3072489798069, 'step': 644},\n",
       "  {'loss': 0.3412773907184601, 'step': 645},\n",
       "  {'loss': 0.9162366986274719, 'step': 646},\n",
       "  {'loss': 0.7604102492332458, 'step': 647},\n",
       "  {'loss': 0.3170093894004822, 'step': 648},\n",
       "  {'loss': 0.6832610368728638, 'step': 649},\n",
       "  {'loss': 1.0910197496414185, 'step': 650},\n",
       "  {'loss': 0.5347052216529846, 'step': 651},\n",
       "  {'loss': 0.4154305160045624, 'step': 652},\n",
       "  {'loss': 0.4852111339569092, 'step': 653},\n",
       "  {'loss': 0.5249656438827515, 'step': 654},\n",
       "  {'loss': 0.25626158714294434, 'step': 655},\n",
       "  {'loss': 0.35400328040122986, 'step': 656},\n",
       "  {'loss': 0.30216914415359497, 'step': 657},\n",
       "  {'loss': 0.42009875178337097, 'step': 658},\n",
       "  {'loss': 0.8018942475318909, 'step': 659},\n",
       "  {'loss': 0.3268643021583557, 'step': 660},\n",
       "  {'loss': 0.6437893509864807, 'step': 661},\n",
       "  {'loss': 0.5324532389640808, 'step': 662},\n",
       "  {'loss': 0.7833386659622192, 'step': 663},\n",
       "  {'loss': 0.28062528371810913, 'step': 664},\n",
       "  {'loss': 0.2349570393562317, 'step': 665},\n",
       "  {'loss': 0.2102237194776535, 'step': 666},\n",
       "  {'loss': 0.3413390815258026, 'step': 667},\n",
       "  {'loss': 0.25312116742134094, 'step': 668},\n",
       "  {'loss': 0.6916089057922363, 'step': 669},\n",
       "  {'loss': 0.5971774458885193, 'step': 670},\n",
       "  {'loss': 1.5339196920394897, 'step': 671},\n",
       "  {'loss': 0.2623533308506012, 'step': 672},\n",
       "  {'loss': 0.2560957074165344, 'step': 673},\n",
       "  {'loss': 0.6181667447090149, 'step': 674},\n",
       "  {'loss': 0.2662544250488281, 'step': 675},\n",
       "  {'loss': 0.5437859296798706, 'step': 676},\n",
       "  {'loss': 0.7009601593017578, 'step': 677},\n",
       "  {'loss': 0.7907558083534241, 'step': 678},\n",
       "  {'loss': 0.6681426763534546, 'step': 679},\n",
       "  {'loss': 0.46428948640823364, 'step': 680},\n",
       "  {'loss': 0.3075990676879883, 'step': 681},\n",
       "  {'loss': 0.32857394218444824, 'step': 682},\n",
       "  {'loss': 0.5906080007553101, 'step': 683},\n",
       "  {'loss': 0.14852029085159302, 'step': 684},\n",
       "  {'loss': 0.6325393319129944, 'step': 685},\n",
       "  {'loss': 0.3006218671798706, 'step': 686},\n",
       "  {'loss': 0.3367469310760498, 'step': 687},\n",
       "  {'loss': 0.8349757790565491, 'step': 688},\n",
       "  {'loss': 0.605133593082428, 'step': 689},\n",
       "  {'loss': 0.3060750961303711, 'step': 690},\n",
       "  {'loss': 0.8568702936172485, 'step': 691},\n",
       "  {'loss': 0.7798622846603394, 'step': 692},\n",
       "  {'loss': 0.8027433156967163, 'step': 693},\n",
       "  {'loss': 0.26966264843940735, 'step': 694},\n",
       "  {'loss': 0.4589439630508423, 'step': 695},\n",
       "  {'loss': 0.4376600384712219, 'step': 696},\n",
       "  {'loss': 1.1544817686080933, 'step': 697},\n",
       "  {'loss': 0.29323914647102356, 'step': 698},\n",
       "  {'loss': 0.3490644097328186, 'step': 699},\n",
       "  {'loss': 0.5168858170509338, 'step': 700},\n",
       "  {'loss': 1.008017897605896, 'step': 701},\n",
       "  {'loss': 0.3399648070335388, 'step': 702},\n",
       "  {'loss': 0.3086806535720825, 'step': 703},\n",
       "  {'loss': 0.585747480392456, 'step': 704},\n",
       "  {'loss': 0.2212018072605133, 'step': 705},\n",
       "  {'loss': 0.30961912870407104, 'step': 706},\n",
       "  {'loss': 0.43525630235671997, 'step': 707},\n",
       "  {'loss': 0.4046470820903778, 'step': 708},\n",
       "  {'loss': 0.7602893114089966, 'step': 709},\n",
       "  {'loss': 0.7610015869140625, 'step': 710},\n",
       "  {'loss': 0.5263271331787109, 'step': 711},\n",
       "  {'loss': 0.8219871520996094, 'step': 712},\n",
       "  {'loss': 0.5554556250572205, 'step': 713},\n",
       "  {'loss': 0.8861128687858582, 'step': 714},\n",
       "  {'loss': 0.873259425163269, 'step': 715},\n",
       "  {'loss': 0.5300067067146301, 'step': 716},\n",
       "  {'loss': 0.6622158885002136, 'step': 717},\n",
       "  {'loss': 0.33917272090911865, 'step': 718},\n",
       "  {'loss': 0.3714626133441925, 'step': 719},\n",
       "  {'loss': 0.39112889766693115, 'step': 720},\n",
       "  {'loss': 0.582304835319519, 'step': 721},\n",
       "  {'loss': 0.3996579349040985, 'step': 722},\n",
       "  {'loss': 0.7897383570671082, 'step': 723},\n",
       "  {'loss': 0.5320801734924316, 'step': 724},\n",
       "  {'loss': 0.9962932467460632, 'step': 725},\n",
       "  {'loss': 0.2876112759113312, 'step': 726},\n",
       "  {'loss': 0.24926558136940002, 'step': 727},\n",
       "  {'loss': 0.31587401032447815, 'step': 728},\n",
       "  {'loss': 0.6987789273262024, 'step': 729},\n",
       "  {'loss': 0.795287013053894, 'step': 730},\n",
       "  {'loss': 0.19284236431121826, 'step': 731},\n",
       "  {'loss': 0.2664419710636139, 'step': 732},\n",
       "  {'loss': 0.4058910012245178, 'step': 733},\n",
       "  {'loss': 0.649050235748291, 'step': 734},\n",
       "  {'loss': 0.1673738956451416, 'step': 735},\n",
       "  {'loss': 0.17987185716629028, 'step': 736},\n",
       "  {'loss': 0.20742884278297424, 'step': 737},\n",
       "  {'loss': 0.48137786984443665, 'step': 738},\n",
       "  {'loss': 0.1703411340713501, 'step': 739},\n",
       "  {'loss': 0.2987867295742035, 'step': 740},\n",
       "  {'loss': 0.3230377733707428, 'step': 741},\n",
       "  {'loss': 0.2291664481163025, 'step': 742},\n",
       "  {'loss': 0.200309157371521, 'step': 743},\n",
       "  {'loss': 0.21466395258903503, 'step': 744},\n",
       "  {'loss': 0.17052152752876282, 'step': 745},\n",
       "  {'loss': 0.5716515183448792, 'step': 746},\n",
       "  {'loss': 1.646719217300415, 'step': 747},\n",
       "  {'loss': 0.2690697908401489, 'step': 748},\n",
       "  {'loss': 0.6061270236968994, 'step': 749},\n",
       "  {'loss': 0.8207476139068604, 'step': 750},\n",
       "  {'loss': 0.39407026767730713, 'step': 751},\n",
       "  {'loss': 0.16482526063919067, 'step': 752},\n",
       "  {'loss': 0.6012364625930786, 'step': 753},\n",
       "  {'loss': 0.24137483537197113, 'step': 754},\n",
       "  {'loss': 0.7680120468139648, 'step': 755},\n",
       "  {'loss': 0.5366567969322205, 'step': 756},\n",
       "  {'loss': 0.5663530230522156, 'step': 757},\n",
       "  {'loss': 0.1450001299381256, 'step': 758},\n",
       "  {'loss': 0.29714247584342957, 'step': 759},\n",
       "  {'loss': 0.6175885796546936, 'step': 760},\n",
       "  {'loss': 0.6952789425849915, 'step': 761},\n",
       "  {'loss': 0.7209597229957581, 'step': 762},\n",
       "  {'loss': 1.0197157859802246, 'step': 763},\n",
       "  {'loss': 0.9999207854270935, 'step': 764},\n",
       "  {'loss': 0.6811842322349548, 'step': 765},\n",
       "  {'loss': 0.40085774660110474, 'step': 766},\n",
       "  {'loss': 0.39989954233169556, 'step': 767},\n",
       "  {'loss': 0.32626426219940186, 'step': 768},\n",
       "  {'loss': 0.3343711495399475, 'step': 769},\n",
       "  {'loss': 1.0192229747772217, 'step': 770},\n",
       "  {'loss': 0.5844051837921143, 'step': 771},\n",
       "  {'loss': 0.4865855276584625, 'step': 772},\n",
       "  {'loss': 0.1826637089252472, 'step': 773},\n",
       "  {'loss': 0.3758411705493927, 'step': 774},\n",
       "  {'loss': 0.6503866314888, 'step': 775},\n",
       "  {'loss': 0.13922038674354553, 'step': 776},\n",
       "  {'loss': 0.2030378133058548, 'step': 777},\n",
       "  {'loss': 0.24368642270565033, 'step': 778},\n",
       "  {'loss': 0.34041067957878113, 'step': 779},\n",
       "  {'loss': 0.37072741985321045, 'step': 780},\n",
       "  {'loss': 0.6070154309272766, 'step': 781},\n",
       "  {'loss': 0.33382880687713623, 'step': 782},\n",
       "  {'loss': 0.3392704725265503, 'step': 783},\n",
       "  {'loss': 0.33594775199890137, 'step': 784},\n",
       "  {'loss': 0.730309247970581, 'step': 785},\n",
       "  {'loss': 0.36469849944114685, 'step': 786},\n",
       "  {'loss': 0.37280064821243286, 'step': 787},\n",
       "  {'loss': 0.2360145002603531, 'step': 788},\n",
       "  {'loss': 0.3711572289466858, 'step': 789},\n",
       "  {'loss': 0.8777353167533875, 'step': 790},\n",
       "  {'loss': 0.35694628953933716, 'step': 791},\n",
       "  {'loss': 0.6678522825241089, 'step': 792},\n",
       "  {'loss': 0.40355539321899414, 'step': 793},\n",
       "  {'loss': 0.2950873374938965, 'step': 794},\n",
       "  {'loss': 1.1705892086029053, 'step': 795},\n",
       "  {'loss': 0.7119101285934448, 'step': 796},\n",
       "  {'loss': 0.11302743852138519, 'step': 797},\n",
       "  {'loss': 0.5917925238609314, 'step': 798},\n",
       "  {'loss': 0.2540552616119385, 'step': 799},\n",
       "  {'loss': 0.5236687660217285, 'step': 800},\n",
       "  {'loss': 0.4350113570690155, 'step': 801},\n",
       "  {'loss': 0.48517829179763794, 'step': 802},\n",
       "  {'loss': 0.40254801511764526, 'step': 803},\n",
       "  {'loss': 0.9627475738525391, 'step': 804},\n",
       "  {'loss': 0.15103308856487274, 'step': 805},\n",
       "  {'loss': 0.4988101124763489, 'step': 806},\n",
       "  {'loss': 0.2168489694595337, 'step': 807},\n",
       "  {'loss': 0.4358102083206177, 'step': 808},\n",
       "  {'loss': 0.3177465796470642, 'step': 809},\n",
       "  {'loss': 0.689956545829773, 'step': 810},\n",
       "  {'loss': 0.5135996341705322, 'step': 811},\n",
       "  {'loss': 0.22518138587474823, 'step': 812},\n",
       "  {'loss': 0.5657521486282349, 'step': 813},\n",
       "  {'loss': 1.3614170551300049, 'step': 814},\n",
       "  {'loss': 0.19886022806167603, 'step': 815},\n",
       "  {'loss': 0.564987301826477, 'step': 816},\n",
       "  {'loss': 0.6270337700843811, 'step': 817},\n",
       "  {'loss': 0.46315696835517883, 'step': 818},\n",
       "  {'loss': 0.8308767676353455, 'step': 819},\n",
       "  {'loss': 0.6889512538909912, 'step': 820},\n",
       "  {'loss': 0.5957233905792236, 'step': 821},\n",
       "  {'loss': 0.8593367338180542, 'step': 822},\n",
       "  {'loss': 0.422538697719574, 'step': 823},\n",
       "  {'loss': 0.24222129583358765, 'step': 824},\n",
       "  {'loss': 0.1909554898738861, 'step': 825},\n",
       "  {'loss': 0.6708430647850037, 'step': 826},\n",
       "  {'loss': 0.28688937425613403, 'step': 827},\n",
       "  {'loss': 0.21899428963661194, 'step': 828},\n",
       "  {'loss': 0.19781681895256042, 'step': 829},\n",
       "  {'loss': 0.5037932991981506, 'step': 830},\n",
       "  {'loss': 0.4887305498123169, 'step': 831},\n",
       "  {'loss': 0.40106695890426636, 'step': 832},\n",
       "  {'loss': 0.45800358057022095, 'step': 833},\n",
       "  {'loss': 0.2995143234729767, 'step': 834},\n",
       "  {'loss': 0.4898761510848999, 'step': 835},\n",
       "  {'loss': 1.2049686908721924, 'step': 836},\n",
       "  {'loss': 0.5255818367004395, 'step': 837},\n",
       "  {'loss': 0.39014896750450134, 'step': 838},\n",
       "  {'loss': 0.32365840673446655, 'step': 839},\n",
       "  {'loss': 0.3285321295261383, 'step': 840},\n",
       "  {'loss': 0.3448711037635803, 'step': 841},\n",
       "  {'loss': 0.21354475617408752, 'step': 842},\n",
       "  {'loss': 0.7800565361976624, 'step': 843},\n",
       "  {'loss': 0.2651447653770447, 'step': 844},\n",
       "  {'loss': 0.43673938512802124, 'step': 845},\n",
       "  {'loss': 0.7192643284797668, 'step': 846},\n",
       "  {'loss': 0.31789126992225647, 'step': 847},\n",
       "  {'loss': 0.145123690366745, 'step': 848},\n",
       "  {'loss': 0.10066778212785721, 'step': 849},\n",
       "  {'loss': 3.136983633041382, 'step': 850},\n",
       "  {'loss': 0.7178380489349365, 'step': 851},\n",
       "  {'loss': 0.4073864221572876, 'step': 852},\n",
       "  {'loss': 0.21710450947284698, 'step': 853},\n",
       "  {'loss': 0.2515203356742859, 'step': 854},\n",
       "  {'loss': 0.10906082391738892, 'step': 855},\n",
       "  {'loss': 0.23240098357200623, 'step': 856},\n",
       "  {'loss': 0.053557850420475006, 'step': 857},\n",
       "  {'loss': 0.4497108459472656, 'step': 858},\n",
       "  {'loss': 0.40042370557785034, 'step': 859},\n",
       "  {'loss': 0.22392141819000244, 'step': 860},\n",
       "  {'loss': 0.44632190465927124, 'step': 861},\n",
       "  {'loss': 0.7004079222679138, 'step': 862},\n",
       "  {'loss': 0.34958383440971375, 'step': 863},\n",
       "  {'loss': 0.3644622266292572, 'step': 864},\n",
       "  {'loss': 0.36820560693740845, 'step': 865},\n",
       "  {'loss': 0.18171197175979614, 'step': 866},\n",
       "  {'loss': 0.7043233513832092, 'step': 867},\n",
       "  {'loss': 0.6189899444580078, 'step': 868},\n",
       "  {'loss': 0.2912342846393585, 'step': 869},\n",
       "  {'loss': 0.25585272908210754, 'step': 870},\n",
       "  {'loss': 0.7106519937515259, 'step': 871},\n",
       "  {'loss': 0.8600575923919678, 'step': 872},\n",
       "  {'loss': 0.38369888067245483, 'step': 873},\n",
       "  {'loss': 0.41856977343559265, 'step': 874},\n",
       "  {'loss': 0.1142866313457489, 'step': 875},\n",
       "  {'loss': 0.6469531059265137, 'step': 876},\n",
       "  {'loss': 0.8138896226882935, 'step': 877},\n",
       "  {'loss': 0.2358972281217575, 'step': 878},\n",
       "  {'loss': 0.3048363924026489, 'step': 879},\n",
       "  {'loss': 0.6164259910583496, 'step': 880},\n",
       "  {'loss': 0.2827364206314087, 'step': 881},\n",
       "  {'loss': 0.4993470311164856, 'step': 882},\n",
       "  {'loss': 0.10667087882757187, 'step': 883},\n",
       "  {'loss': 0.42663800716400146, 'step': 884},\n",
       "  {'loss': 0.43008360266685486, 'step': 885},\n",
       "  {'loss': 0.2687481641769409, 'step': 886},\n",
       "  {'loss': 0.4434449076652527, 'step': 887},\n",
       "  {'loss': 0.21483400464057922, 'step': 888},\n",
       "  {'loss': 0.37292706966400146, 'step': 889},\n",
       "  {'loss': 0.3786133825778961, 'step': 890},\n",
       "  {'loss': 0.6922844052314758, 'step': 891},\n",
       "  {'loss': 0.1760891228914261, 'step': 892},\n",
       "  {'loss': 0.17569507658481598, 'step': 893},\n",
       "  {'loss': 0.7806593179702759, 'step': 894},\n",
       "  {'loss': 0.42959320545196533, 'step': 895},\n",
       "  {'loss': 0.25225770473480225, 'step': 896},\n",
       "  {'loss': 0.32424241304397583, 'step': 897},\n",
       "  {'loss': 0.29839998483657837, 'step': 898},\n",
       "  {'loss': 0.9126385450363159, 'step': 899},\n",
       "  {'loss': 0.7868523001670837, 'step': 900},\n",
       "  {'loss': 0.3507068157196045, 'step': 901},\n",
       "  {'loss': 0.38091063499450684, 'step': 902},\n",
       "  {'loss': 0.45698872208595276, 'step': 903},\n",
       "  {'loss': 0.4074844717979431, 'step': 904},\n",
       "  {'loss': 0.17309927940368652, 'step': 905},\n",
       "  {'loss': 0.41426199674606323, 'step': 906},\n",
       "  {'loss': 0.0728883445262909, 'step': 907},\n",
       "  {'loss': 0.2593286633491516, 'step': 908},\n",
       "  {'loss': 0.37064486742019653, 'step': 909},\n",
       "  {'loss': 0.6817214488983154, 'step': 910},\n",
       "  {'loss': 0.5346371531486511, 'step': 911},\n",
       "  {'loss': 0.7753392457962036, 'step': 912},\n",
       "  {'loss': 0.29200291633605957, 'step': 913},\n",
       "  {'loss': 0.3743438124656677, 'step': 914},\n",
       "  {'loss': 0.4602881073951721, 'step': 915},\n",
       "  {'loss': 0.19897034764289856, 'step': 916},\n",
       "  {'loss': 0.28781402111053467, 'step': 917},\n",
       "  {'loss': 0.5547143220901489, 'step': 918},\n",
       "  {'loss': 0.9660156965255737, 'step': 919},\n",
       "  {'loss': 0.5712073445320129, 'step': 920},\n",
       "  {'loss': 0.3220996856689453, 'step': 921},\n",
       "  {'loss': 0.45423975586891174, 'step': 922},\n",
       "  {'loss': 0.40081971883773804, 'step': 923},\n",
       "  {'loss': 0.5499626398086548, 'step': 924},\n",
       "  {'loss': 0.2852991819381714, 'step': 925},\n",
       "  {'loss': 0.2332175225019455, 'step': 926},\n",
       "  {'loss': 0.4070695638656616, 'step': 927},\n",
       "  {'loss': 0.7052186727523804, 'step': 928},\n",
       "  {'loss': 0.16951432824134827, 'step': 929},\n",
       "  {'loss': 0.266595721244812, 'step': 930},\n",
       "  {'loss': 0.5819294452667236, 'step': 931},\n",
       "  {'loss': 0.2931613326072693, 'step': 932},\n",
       "  {'loss': 0.18334439396858215, 'step': 933},\n",
       "  {'loss': 0.7457518577575684, 'step': 934},\n",
       "  {'loss': 0.4483412504196167, 'step': 935},\n",
       "  {'loss': 0.8216904997825623, 'step': 936},\n",
       "  {'loss': 0.42181020975112915, 'step': 937},\n",
       "  {'loss': 0.26557332277297974, 'step': 938},\n",
       "  {'loss': 0.14760445058345795, 'step': 939},\n",
       "  {'loss': 0.8625407218933105, 'step': 940},\n",
       "  {'loss': 0.2041926383972168, 'step': 941},\n",
       "  {'loss': 0.3188810348510742, 'step': 942},\n",
       "  {'loss': 0.5211763978004456, 'step': 943},\n",
       "  {'loss': 0.3394540548324585, 'step': 944},\n",
       "  {'loss': 0.27106013894081116, 'step': 945},\n",
       "  {'loss': 0.5688269734382629, 'step': 946},\n",
       "  {'loss': 0.4252344071865082, 'step': 947},\n",
       "  {'loss': 0.23199456930160522, 'step': 948},\n",
       "  {'loss': 0.6973408460617065, 'step': 949},\n",
       "  {'loss': 0.4230841398239136, 'step': 950},\n",
       "  {'loss': 1.1009716987609863, 'step': 951},\n",
       "  {'loss': 0.24348706007003784, 'step': 952},\n",
       "  {'loss': 0.3535982072353363, 'step': 953},\n",
       "  {'loss': 0.1574172079563141, 'step': 954},\n",
       "  {'loss': 1.2178455591201782, 'step': 955},\n",
       "  {'loss': 0.23850679397583008, 'step': 956},\n",
       "  {'loss': 0.4286310076713562, 'step': 957},\n",
       "  {'loss': 10.747323989868164, 'step': 958},\n",
       "  {'loss': 1.2270128726959229, 'step': 959},\n",
       "  {'loss': 0.4976511597633362, 'step': 960},\n",
       "  {'loss': 0.9504871368408203, 'step': 961},\n",
       "  {'loss': 0.6873970627784729, 'step': 962},\n",
       "  {'loss': 0.274894118309021, 'step': 963},\n",
       "  {'loss': 1.0234606266021729, 'step': 964},\n",
       "  {'loss': 0.34316855669021606, 'step': 965},\n",
       "  {'loss': 0.4878654479980469, 'step': 966},\n",
       "  {'loss': 0.41637349128723145, 'step': 967},\n",
       "  {'loss': 0.5381747484207153, 'step': 968},\n",
       "  {'loss': 0.22980764508247375, 'step': 969},\n",
       "  {'loss': 0.12114258855581284, 'step': 970},\n",
       "  {'loss': 0.6958239078521729, 'step': 971},\n",
       "  {'loss': 0.2735171318054199, 'step': 972},\n",
       "  {'loss': 1.234015941619873, 'step': 973},\n",
       "  {'loss': 0.5050225853919983, 'step': 974},\n",
       "  {'loss': 0.2653689980506897, 'step': 975},\n",
       "  {'loss': 0.38679423928260803, 'step': 976},\n",
       "  {'loss': 0.29210665822029114, 'step': 977},\n",
       "  {'loss': 1.19733464717865, 'step': 978},\n",
       "  {'loss': 0.24317041039466858, 'step': 979},\n",
       "  {'loss': 0.15908437967300415, 'step': 980},\n",
       "  {'loss': 0.3788924217224121, 'step': 981},\n",
       "  {'loss': 0.9108093976974487, 'step': 982},\n",
       "  {'loss': 0.40924352407455444, 'step': 983},\n",
       "  {'loss': 0.4937705993652344, 'step': 984},\n",
       "  {'loss': 0.21928629279136658, 'step': 985},\n",
       "  {'loss': 0.18130247294902802, 'step': 986},\n",
       "  {'loss': 0.3860171437263489, 'step': 987},\n",
       "  {'loss': 0.9624167680740356, 'step': 988},\n",
       "  {'loss': 0.9249244332313538, 'step': 989},\n",
       "  {'loss': 0.8306124210357666, 'step': 990},\n",
       "  {'loss': 1.1318557262420654, 'step': 991},\n",
       "  {'loss': 0.3341487944126129, 'step': 992},\n",
       "  {'loss': 0.3928096294403076, 'step': 993},\n",
       "  {'loss': 0.24416589736938477, 'step': 994},\n",
       "  {'loss': 1.057608962059021, 'step': 995},\n",
       "  {'loss': 1.027411699295044, 'step': 996},\n",
       "  {'loss': 0.7839064598083496, 'step': 997},\n",
       "  {'loss': 0.2767539620399475, 'step': 998},\n",
       "  {'loss': 0.40120041370391846, 'step': 999},\n",
       "  ...],\n",
       " 'val': [{'loss': np.float64(6.482116768182802), 'step': 0},\n",
       "  {'loss': np.float64(0.5331369055327305), 'step': 726},\n",
       "  {'loss': np.float64(0.4678933389854333), 'step': 1452},\n",
       "  {'loss': np.float64(0.4473868685751414), 'step': 2178},\n",
       "  {'loss': np.float64(0.4213750093005413), 'step': 2904},\n",
       "  {'loss': np.float64(0.4114514820216116), 'step': 3630},\n",
       "  {'loss': np.float64(0.4010359621491314), 'step': 4356},\n",
       "  {'loss': np.float64(0.4035325556808759), 'step': 5082},\n",
       "  {'loss': np.float64(0.3910686907566283), 'step': 5808},\n",
       "  {'loss': np.float64(0.38388258671341846), 'step': 6534},\n",
       "  {'loss': np.float64(0.38115814565257594), 'step': 7260},\n",
       "  {'loss': np.float64(0.3788260332624282), 'step': 7986},\n",
       "  {'loss': np.float64(0.37010340331014524), 'step': 8712},\n",
       "  {'loss': np.float64(0.36769599171955725), 'step': 9438},\n",
       "  {'loss': np.float64(0.3754415833198827), 'step': 10164},\n",
       "  {'loss': np.float64(0.38683024886225864), 'step': 10890},\n",
       "  {'loss': np.float64(0.36691214442868864), 'step': 11616},\n",
       "  {'loss': np.float64(0.3700078843423158), 'step': 12342},\n",
       "  {'loss': np.float64(0.36342587574454377), 'step': 13068},\n",
       "  {'loss': np.float64(0.3608489646614829), 'step': 13794},\n",
       "  {'loss': np.float64(0.3584781005855434), 'step': 14520},\n",
       "  {'loss': np.float64(0.350729020666485), 'step': 15246},\n",
       "  {'loss': np.float64(0.3686456568847018), 'step': 15972},\n",
       "  {'loss': np.float64(0.3499698352745988), 'step': 16698},\n",
       "  {'loss': np.float64(0.3466174116373555), 'step': 17424},\n",
       "  {'loss': np.float64(0.3454483526889697), 'step': 18150},\n",
       "  {'loss': np.float64(0.3491544868519976), 'step': 18876},\n",
       "  {'loss': np.float64(0.3488537970591675), 'step': 19602},\n",
       "  {'loss': np.float64(0.34815959192135115), 'step': 20328},\n",
       "  {'loss': np.float64(0.36411782535762827), 'step': 21054},\n",
       "  {'loss': np.float64(0.349607853419032), 'step': 21780},\n",
       "  {'loss': np.float64(0.343688381728062), 'step': 22506},\n",
       "  {'loss': np.float64(0.3513064229137395), 'step': 23232},\n",
       "  {'loss': np.float64(0.33987099294019635), 'step': 23958},\n",
       "  {'loss': np.float64(0.33853881519811213), 'step': 24684},\n",
       "  {'loss': np.float64(0.34186664961032137), 'step': 25410},\n",
       "  {'loss': np.float64(0.3454057518854614), 'step': 26136},\n",
       "  {'loss': np.float64(0.3387582176326474), 'step': 26862},\n",
       "  {'loss': np.float64(0.33507659960507363), 'step': 27588},\n",
       "  {'loss': np.float64(0.3319085318410446), 'step': 28314},\n",
       "  {'loss': np.float64(0.34716181487830217), 'step': 29040},\n",
       "  {'loss': np.float64(0.331918909668553), 'step': 29766},\n",
       "  {'loss': np.float64(0.3414971226256741), 'step': 30492},\n",
       "  {'loss': np.float64(0.3305846011219931), 'step': 31218},\n",
       "  {'loss': np.float64(0.32988984594968235), 'step': 31944},\n",
       "  {'loss': np.float64(0.3256507627358121), 'step': 32670},\n",
       "  {'loss': np.float64(0.3394044540699356), 'step': 33396},\n",
       "  {'loss': np.float64(0.3262195222633929), 'step': 34122},\n",
       "  {'loss': np.float64(0.32993557528892825), 'step': 34848},\n",
       "  {'loss': np.float64(0.32333588774108196), 'step': 35574},\n",
       "  {'loss': np.float64(0.327063195961566), 'step': 36300},\n",
       "  {'loss': np.float64(0.3209178783615266), 'step': 37026},\n",
       "  {'loss': np.float64(0.3330588262866844), 'step': 37752},\n",
       "  {'loss': np.float64(0.32094583826616774), 'step': 38478},\n",
       "  {'loss': np.float64(0.3256099346317043), 'step': 39204},\n",
       "  {'loss': np.float64(0.3227463075814168), 'step': 39930},\n",
       "  {'loss': np.float64(0.31860540229981105), 'step': 40656},\n",
       "  {'loss': np.float64(0.32686288316141476), 'step': 41382},\n",
       "  {'loss': np.float64(0.3265542015895124), 'step': 42108},\n",
       "  {'loss': np.float64(0.31800138531637584), 'step': 42834},\n",
       "  {'loss': np.float64(0.32337832709481895), 'step': 43560},\n",
       "  {'loss': np.float64(0.31853148944614346), 'step': 44286},\n",
       "  {'loss': np.float64(0.3225196573175182), 'step': 45012},\n",
       "  {'loss': np.float64(0.320805550591389), 'step': 45738},\n",
       "  {'loss': np.float64(0.3237014970134112), 'step': 46464},\n",
       "  {'loss': np.float64(0.3204181090089654), 'step': 47190},\n",
       "  {'loss': np.float64(0.31877826899290085), 'step': 47916}]}"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 18
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-06T01:05:36.585056Z",
     "start_time": "2025-03-06T01:05:36.490214Z"
    }
   },
   "source": [
    "#画线要注意的是损失是不一定在零到1之间的\n",
    "def plot_learning_curves(record_dict, sample_step=500):\n",
    "    # build DataFrame\n",
    "    train_df = pd.DataFrame(record_dict[\"train\"]).set_index(\"step\").iloc[::sample_step]\n",
    "    val_df = pd.DataFrame(record_dict[\"val\"]).set_index(\"step\")\n",
    "\n",
    "    # plot\n",
    "    for idx, item in enumerate(train_df.columns):\n",
    "        plt.plot(train_df.index, train_df[item], label=f\"train_{item}\")\n",
    "        plt.plot(val_df.index, val_df[item], label=f\"val_{item}\")\n",
    "        plt.grid()\n",
    "        plt.legend()\n",
    "        # plt.xticks(range(0, train_df.index[-1], 10*sample_step), range(0, train_df.index[-1], 10*sample_step))\n",
    "        plt.xlabel(\"step\")\n",
    "\n",
    "        plt.show()\n",
    "\n",
    "plot_learning_curves(record)  #横坐标是 steps"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ],
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAikAAAGwCAYAAABsEvUIAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/TGe4hAAAACXBIWXMAAA9hAAAPYQGoP6dpAABwYklEQVR4nO3dd3gUdf4H8PdsT9v0CknovUgXQUSqqIidQ1RAz9MTK6en3p0Keoqnnj88C+pZ0DsRy4kVkEhHeu89IQHSQ/r2nd8fszPpIZu22cn79Tx5ILuTndnvtvd+vmUEURRFEBEREbUxGl8fABEREVFtGFKIiIioTWJIISIiojaJIYWIiIjaJIYUIiIiapMYUoiIiKhNYkghIiKiNknX2jt0u924cOECQkJCIAhCa++eiIiIGkEURZSUlCAhIQEaTevUOFo9pFy4cAGJiYmtvVsiIiJqBhkZGejYsWOr7KvVQ0pISAgA6U6azeZmu12Hw4HVq1dj0qRJ0Ov1zXa7VD+2u2+w3X2D7e47bHvfqNzuFosFiYmJyud4a2j1kCJ38ZjN5mYPKYGBgTCbzXwCtyK2u2+w3X2D7e47bHvfqK3dW3OoBgfOEhERUZvEkEJERERtEkMKERERtUmtPiaFiIjUx+12w263t9jtOxwO6HQ6WK1WuFyuFttPe6bX66HVan19GFUwpBARUZPY7XakpqbC7Xa32D5EUURcXBwyMjK4xlYLCgsLQ1xcXJtpY4YUIiJqNFEUkZmZCa1Wi8TExBZb5MvtdqO0tBTBwcGttpBYeyKKIsrLy5GTkwMAiI+P9/ERSRhSiIio0ZxOJ8rLy5GQkIDAwMAW24/cnWQymRhSWkhAQAAAICcnBzExMW2i64ePNBERNZo8PsRgMPj4SKg5yEHT4XD4+EgkDClERNRkbWUMAzVNW3scGVKIiIioTWJIISIiojaJIYWIiKgJOnXqhEWLFjXLba1fvx6CIKCwsLBZbs/fqWd2T0kmAm25gMsO8ORTRERUj7Fjx+Kyyy5rlnCxc+dOBAUFNf2gqAbVhBTdR+MwsSwXjlHDgQ4DfH04RETkx0RRhMvlgk536Y/J6OjoVjii9kk93T0azxPJ1XLLMhMRUf1EUUS53dkiPxa7q97rRVFs0DHOnj0bGzZswJtvvglBECAIApYsWQJBELBy5UoMGTIERqMRmzdvxunTpzFt2jTExsYiODgYw4YNw6+//lrl9qp39wiCgA8//BA33XQTAgMD0b17d/zwww+NbtP//e9/6Nu3L4xGIzp16oR//vOfVa5/99130b17d5hMJsTGxuLWW29Vrvvmm2/Qv39/BAQEIDIyEhMmTEBZWVmjj6W1qaaSAq00R19wt4253URE7ZHF4UKf537xyb6PvDAZgYZLf6y9+eabOHHiBPr164cXXngBAHD48GEAwNNPP43XX38dXbp0QXh4ODIyMnDttdfipZdegtFoxGeffYapU6fi+PHjSEpKqnMfCxYswKuvvorXXnsNb731FmbOnImzZ88iIiLCq/u0e/du3H777Zg/fz6mT5+OLVu24MEHH0RkZCRmz56NXbt24ZFHHsF//vMfXHHFFSgoKMCmTZsAAJmZmZgxYwZeffVV3HTTTSgpKcGmTZsaHObaAvWEFKWSwpBCRER1Cw0NhcFgQGBgIOLi4gAAx44dAwC88MILmDhxorJtREQEBg4cqPz+4osvYvny5fjhhx/w0EMP1bmP2bNnY8aMGQCAl19+Gf/617+wY8cOXHPNNV4d6xtvvIHx48fj2WefBQD06NEDR44cwWuvvYbZs2cjPT0dQUFBuP766xESEoLk5GQMGjQIgBRSnE4nbr75ZiQnJwMA+vfv79X+fU09IcVTSWFIISLynQC9FkdemNzst+t2u1FSXIIQc0idy+IH6Ju+jPvQoUOr/F5aWor58+fj559/Vj70LRYL0tPT672dAQMqxkYGBQXBbDYr58XxxtGjRzFt2rQql40aNQqLFi2Cy+XCxIkTkZycjC5duuCaa67BNddco3QzDRw4EOPHj0f//v0xefJkTJo0CbfeeivCw8O9Pg5fUc+YFK1nRg+7e4iIfEYQBAQadC3yE2DQ1nt9c6yWWn2WzhNPPIHly5fj5ZdfxqZNm7Bv3z70798fdnv94x/11WaZCoLQImeJDgkJwZ49e/DFF18gPj4ezz33HAYOHIjCwkJotVqkpKRg5cqV6NOnD9566y307NkTqampzX4cLUU1IUXUeJ4QHDhLRESXYDAYlPMO1ee3337D7NmzcdNNN6F///6Ii4tDWlpayx+gR+/evfHbb7/VOKYePXooJwDU6XSYMGECXn31VRw4cABpaWlYu3YtACkcjRo1CgsWLMDevXthMBiwfPnyVjv+plJRd48c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oIgi2721VA8pbPeWMX36dDE+Pl40GAxihw4dxOnTp4unTp1Srve3dhdEURS9q70QERERtTy/H5NCRERE6sSQQkRERG0SQwoRERG1SQwpRERE1CYxpBAREVGbxJBCREREbRJDChEREbVJDClERETUJjGkEBERUZvEkEJEXpk9ezZuvPFGXx8GEbUDDClERETUJjGkEFGtvvnmG/Tv3x8BAQGIjIzEhAkT8OSTT+LTTz/F999/D0EQIAgC1q9fDwDIyMjA7bffjrCwMERERGDatGlIS0tTbk+uwCxYsADR0dEwm8144IEHYLfbfXMHiajN0/n6AIio7cnMzMSMGTPw6quv4qabbkJJSQk2bdqEu+++G+np6SguLsYnn3wCAIiIiIDD4cDkyZMxcuRIbNq0CTqdDn//+99xzTXX4MCBAzAYDACANWvWwGQyYf369UhLS8OcOXMQGRmJl156yZd3l4jaKIYUIqohMzMTTqcTN998M5KTkwEA/fv3BwAEBATAZrMhLi5O2f6///0v3G43PvzwQwiCAAD45JNPEBYWhvXr12PSpEkAAIPBgI8//hiBgYHo27cvXnjhBTz55JN48cUXodGwsEtEVfFdgYhqGDhwIMaPH4/+/fvjtttuw7///W9cvHixzu3379+PU6dOISQkBMHBwQgODkZERASsVitOnz5d5XYDAwOV30eOHInS0lJkZGS06P0hIv/ESgoR1aDVapGSkoItW7Zg9erVeOutt/DXv/4V27dvr3X70tJSDBkyBJ9//nmN66Kjo1v6cIlIpRhSiKhWgiBg1KhRGDVqFJ577jkkJydj+fLlMBgMcLlcVbYdPHgwvvzyS8TExMBsNtd5m/v374fFYkFAQAAAYNu2bQgODkZiYmKL3hci8k/s7iGiGrZv346XX34Zu3btQnp6Or799lvk5uaid+/e6NSpEw4cOIDjx48jLy8PDocDM2fORFRUFKZNm4ZNmzYhNTUV69evxyOPPIJz584pt2u323HvvffiyJEjWLFiBZ5//nk89NBDHI9CRLViJYWIajCbzdi4cSMWLVqE4uJiJCcn45///CemTJmCoUOHYv369Rg6dChKS0uxbt06jB07Fhs3bsRTTz2Fm2++GSUlJejQoQPGjx9fpbIyfvx4dO/eHWPGjIHNZsOMGTMwf/58391RImrTBFEURV8fBBGp3+zZs1FYWIjvvvvO14dCRH6CNVYiIiJqkxhSiIiIqE1idw8RERG1SaykEBERUZvEkEJERERtEkMKERERtUkMKURERNQmMaQQERFRm8SQQkRERG0SQwoRERG1SQwpRERE1Cb9Py59g4L7vLlbAAAAAElFTkSuQmCC"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "execution_count": 19
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 测试集"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-06T01:05:36.719959Z",
     "start_time": "2025-03-06T01:05:36.585056Z"
    }
   },
   "source": [
    "model.eval()\n",
    "loss = evaluating(model, test_loader, loss_fct)\n",
    "print(f\"loss:     {loss:.4f}\")"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "loss:     0.3231\n"
     ]
    }
   ],
   "execution_count": 20
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "pytorch",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.8"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
